-
1
ActiveAdmin.register_page 'Builders' do
-
1
content do
-
div class: 'index_as_table' do
-
table_for RpmBuildNode.all.to_a.select { |b| b.get_ttl > 0 }, class: "index_table index" do
-
column :id
-
column :user_id do |b|
-
u = User.find(b.user_id) rescue nil
-
if u
-
link_to u.uname, admin_user_path(u.id)
-
else
-
'None'
-
end
-
end
-
column :system
-
column :host
-
column :busy_workers
-
column :query_string do |b|
-
b.query_string.present? ? b.query_string : '-'
-
end
-
column 'Last build ID' do |b|
-
if b.last_build_id.present?
-
link_to b.last_build_id, build_list_path(b.last_build_id)
-
else
-
'None'
-
end
-
end
-
end
-
end
-
end
-
end
-
1
ActiveAdmin.register_page 'Dashboard' do
-
-
1
menu priority: 1
-
-
1
content do
-
-
columns do
-
column do
-
panel "Deploy Information" do
-
require 'deploy_info'
-
-
abf = "https://abf.io/abf/rosa-build/"
-
#jenkins = "https://ci.shuttlerock.com/"
-
-
attributes_table_for DeployInfo do
-
row('Branch') { link_to DeployInfo::BRANCH, "#{abf}tree/#{DeployInfo::BRANCH}" }
-
row('Commit') { link_to DeployInfo::GIT_COMMIT, "#{abf}commit/#{DeployInfo::GIT_COMMIT}" }
-
row('Build Number') { DeployInfo::BUILD_NUMBER }
-
row('Build ID') { DeployInfo::BUILD_ID }
-
row('Deployer') { DeployInfo::DEPLOYER }
-
row(:message) { pre DeployInfo.message }
-
end
-
end # panel
-
end # column
-
end # columns
-
-
-
end # content
-
-
end
-
1
ActiveAdmin.register EventLog do
-
-
1
menu parent: 'Misc'
-
-
1
actions :all, except: %i(create update new edit destroy)
-
-
1
controller do
-
1
def scoped_collection
-
EventLog.includes(:user)
-
end
-
end
-
-
1
index do
-
column :id
-
column :kind
-
column :created_at
-
column :user
-
column :ip
-
column :protocol
-
column('Description') do |el|
-
msg = %w([)
-
msg << I18n.t("event_log.controllers.#{el.controller.underscore}", default: el.controller) << "]"
-
msg << I18n.t("event_log.actions.#{el.controller.underscore}.#{el.action}", default: :"event_log.actions.#{el.action}")
-
if el.eventable_id.present? and el.eventable_type.present?
-
msg << '' << I18n.t("activerecord.models.#{el.eventable_type.underscore}")
-
msg << el.eventable_name
-
msg << "(id##{el.eventable_id})" # link_to "id##{el.eventable_id}", el.eventable
-
end
-
msg << el.message.to_s
-
msg.join(' ')
-
end
-
-
-
actions
-
end
-
-
end
-
1
ActiveAdmin.register FlashNotify do
-
1
permit_params :body_ru, :body_en, :status, :published
-
-
1
menu parent: 'Misc'
-
-
1
index do
-
column :id
-
column(:body_en) do |fn|
-
fn.body_en.truncate(18)
-
end
-
column(:body_ru) do |fn|
-
fn.body_ru.truncate(18)
-
end
-
column :published
-
-
actions
-
end
-
-
1
form do |f|
-
f.inputs do
-
f.input :body_en
-
f.input :body_ru
-
f.input :status, as: :select, collection: FlashNotify::STATUSES, include_blank: false
-
f.input :published
-
end
-
f.actions
-
end
-
-
end
-
1
ActiveAdmin.register_page 'Resque' do
-
1
menu priority: 100, label: 'Resque', url: '/admin/resque/overview'
-
end
-
1
ActiveAdmin.register User do
-
1
permit_params :uname, :name, :email, :password, :password_confirmation
-
-
1
menu priority: 2
-
-
1
filter :uname
-
1
filter :email
-
1
filter :role, as: :select, collection: User::EXTENDED_ROLES
-
1
filter :created_at
-
-
1
controller do
-
1
def update(options={}, &block)
-
user_params = params[:user]
-
resource.role = user_params.delete(:role)
-
user_params.delete(:password) if user_params[:password].blank?
-
user_params.delete(:password_confirmation) if user_params[:password_confirmation].blank?
-
super
-
end
-
end
-
-
1
index do
-
column :id
-
column(:uname) do |user|
-
link_to(user.uname, user_path(user))
-
end
-
column :email
-
column :created_at
-
column :role
-
-
actions
-
end
-
-
1
form do |f|
-
f.inputs do
-
f.input :name
-
f.input :email
-
f.input :uname
-
f.input :role, as: :select, collection: User::EXTENDED_ROLES, include_blank: false
-
f.input :password
-
f.input :password_confirmation
-
end
-
f.actions
-
end
-
-
1
action_item(:reset_token, only: :show) do
-
link_to 'Reset token', reset_token_admin_user_path(resource),
-
'data-method' => :put,
-
data: { confirm: 'Are you sure you want to reset token?' }
-
end
-
-
1
action_item(:login_as, only: :show) do
-
link_to 'Login as user', login_as_admin_user_path(resource)
-
end
-
-
1
member_action :reset_token, :method => :put do
-
resource.reset_authentication_token!
-
flash[:info] = 'User token reseted successfully'
-
redirect_to admin_user_path(resource)
-
end
-
-
1
member_action :login_as do
-
sign_in(resource, bypass: true)
-
redirect_to root_path
-
end
-
-
end
-
1
class AdvisoriesController < ApplicationController
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user! if APP_CONFIG['anonymous_access']
-
-
1
def index
-
authorize :advisory
-
@advisories = Advisory.includes(:platforms, :projects).search_like(params[:q]).distinct
-
@advisories_count = @advisories.count
-
@advisories = @advisories.paginate(page: current_page, per_page: Advisory.per_page)
-
respond_to do |format|
-
format.html
-
format.json
-
format.atom
-
end
-
end
-
-
1
def show
-
authorize @advisory = Advisory.find_by(advisory_id: params[:id])
-
@packages_info = @advisory.fetch_packages_info
-
end
-
-
1
def search
-
authorize :advisory
-
@advisory = Advisory.by_update_type(params[:bl_type]).search_by_id(params[:query]).first
-
if @advisory.nil?
-
head 404
-
else
-
# respond_to do |format|
-
# format.json { render @advisory }
-
# end
-
render @advisory
-
end
-
end
-
end
-
1
class Api::V1::AdvisoriesController < Api::V1::BaseController
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: %i(index show) if APP_CONFIG['anonymous_access']
-
1
before_action :load_advisory, only: %i(show update)
-
1
before_action :load_build_list, only: %i(create update)
-
-
1
def index
-
authorize :advisory
-
@advisories = Advisory.includes(:platforms, :projects).paginate(paginate_params)
-
end
-
-
1
def show
-
@packages_info = @advisory.fetch_packages_info
-
end
-
-
1
def create
-
authorize :advisory
-
if @build_list.can_attach_to_advisory? &&
-
@build_list.associate_and_create_advisory(advisory_params) &&
-
@build_list.save
-
render_json_response @build_list.advisory, 'Advisory has been created successfully'
-
else
-
render_validation_error @build_list.advisory, error_message(@build_list, 'Advisory has not been created')
-
end
-
end
-
-
1
def update
-
if @advisory && @build_list.can_attach_to_advisory? &&
-
@advisory.attach_build_list(@build_list) && @build_list.save
-
render_json_response @advisory, "Build list '#{@build_list.id}' has been attached to advisory successfully"
-
else
-
render_validation_error @advisory, error_message(@build_list, 'Build list has not been attached to advisory')
-
end
-
end
-
-
1
protected
-
-
1
def advisory_params
-
subject_params(Advisory)
-
end
-
-
1
def load_build_list
-
@build_list = BuildList.find params[:build_list_id]
-
authorize @build_list.save_to_platform, :local_admin_manage?
-
end
-
-
1
def load_advisory
-
@advisory = Advisory.find_by(advisory_id: params[:id]) if params[:id]
-
authorize @advisory if @advisory
-
end
-
-
end
-
1
class Api::V1::ArchesController < Api::V1::BaseController
-
1
before_action :authenticate_user! unless APP_CONFIG['anonymous_access']
-
-
1
def index
-
authorize :arch
-
@arches = Arch.order(:id).paginate(paginate_params)
-
end
-
-
end
-
1
class Api::V1::BaseController < ApplicationController
-
1
include PaginateHelper
-
1
respond_to :json
-
-
1
helper_method :member_path
-
-
1
rescue_from Pundit::NotAuthorizedError do |exception|
-
respond_to do |format|
-
format.json { render json: {message: t('flash.exception_message')}.to_json, status: 403 }
-
format.csv { render plain: t('flash.exception_message'), status: 403 }
-
end
-
end
-
-
1
protected
-
-
1
def set_csv_file_headers(file_name)
-
headers['Content-Type'] = 'text/csv'
-
headers['Content-disposition'] = "attachment; filename=\"#{file_name}.csv\""
-
end
-
-
1
def set_streaming_headers
-
# nginx doc: Setting this to "no" will allow unbuffered responses suitable for Comet and HTTP streaming applications
-
headers['X-Accel-Buffering'] = 'no'
-
-
headers['Cache-Control'] ||= 'no-cache'
-
headers.delete 'Content-Length'
-
end
-
-
1
def set_locale
-
I18n.locale = :en
-
end
-
-
1
def error_message(subject, message)
-
[message, subject.errors.map(&:full_message)].flatten.join('. ')
-
end
-
-
1
def create_subject(subject)
-
authorize subject, :create?
-
class_name = subject.class.name
-
if subject.save
-
render_json_response subject, "#{class_name} has been created successfully"
-
else
-
render_validation_error subject, "#{class_name} has not been created"
-
end
-
end
-
-
1
def update_member_in_subject(subject, relation = :relations)
-
authorize subject, :update_member?
-
role = params[:role]
-
class_name = subject.class.name.downcase
-
if member.present? && role.present? && subject.respond_to?(:owner) && subject.owner != member &&
-
subject.send(relation).by_actor(member).update_all(role: role)
-
render_json_response subject, "Role for #{member.class.name.downcase} '#{member.id} has been updated in #{class_name} successfully"
-
else
-
render_validation_error subject, "Role for member has not been updated in #{class_name}"
-
end
-
end
-
-
1
def add_member_to_subject(subject, role = 'admin')
-
authorize subject, :add_member?
-
class_name = subject.class.name.downcase
-
if member.present? && subject.add_member(member, role)
-
render_json_response subject, "#{member.class.to_s} '#{member.id}' has been added to #{class_name} successfully"
-
else
-
render_validation_error subject, "Member has not been added to #{class_name}"
-
end
-
end
-
-
1
def remove_member_from_subject(subject)
-
authorize subject, :remove_member?
-
class_name = subject.class.name.downcase
-
if member.present? && subject.remove_member(member)
-
render_json_response subject, "#{member.class.to_s} '#{member.id}' has been removed from #{class_name} successfully"
-
else
-
render_validation_error subject, "Member has not been removed from #{class_name}"
-
end
-
end
-
-
1
def destroy_subject(subject)
-
authorize subject, :destroy?
-
subject.destroy # later with resque
-
render_json_response subject, "#{subject.class.name} has been destroyed successfully"
-
end
-
-
1
def update_subject(subject)
-
authorize subject, :update?
-
class_name = subject.class.name
-
if subject.update(subject_params(subject.class, subject))
-
render_json_response subject, "#{class_name} has been updated successfully"
-
else
-
render_validation_error subject, "#{class_name} has not been updated"
-
end
-
end
-
-
1
def render_json_response(subject, message, status = 200)
-
id = status != 200 ? nil : subject.id
-
-
render json: {
-
subject.class.name.underscore.to_sym => {
-
id: id,
-
message: message
-
}
-
}, status: status
-
end
-
-
1
def render_validation_error(subject, message)
-
render_json_response(subject, error_message(subject, message), 422)
-
end
-
-
1
def member_path(subject)
-
if subject.is_a?(User)
-
api_v1_user_path(subject.id, format: :json)
-
else
-
api_v1_group_path(subject.id, format: :json)
-
end
-
end
-
-
1
private
-
-
1
def member
-
if @member.blank? && %w(User Group).include?(params[:type])
-
@member = params[:type].constantize.where(id: params[:member_id]).first
-
end
-
@member
-
end
-
-
end
-
1
class Api::V1::BuildListsController < Api::V1::BaseController
-
1
before_action :authenticate_user!
-
1
before_action :load_build_list, only: %i(
-
cancel
-
create_container
-
publish
-
publish_into_testing
-
reject_publish
-
rerun_tests
-
show
-
)
-
1
skip_before_action :authenticate_user!, only: %i(show index) if APP_CONFIG['anonymous_access']
-
-
1
def show
-
authorize @build_list
-
respond_to :json
-
end
-
-
1
def index
-
authorize :build_list
-
@project = Project.find(params[:project_id]) if params[:project_id].present?
-
authorize @project, :show? if @project
-
filter = BuildList::Filter.new(@project, current_user, params[:filter] || {})
-
@build_lists = filter.find.includes(:build_for_platform,
-
:save_to_repository,
-
:save_to_platform,
-
:project,
-
:user,
-
:arch)
-
-
@build_lists = @build_lists.recent.paginate(paginate_params)
-
respond_to :json
-
end
-
-
1
def create
-
save_to_repository = Repository.find_by(id: build_list_params[:save_to_repository_id])
-
-
@build_list = current_user.build_lists.new(build_list_params)
-
@build_list.save_to_platform = save_to_repository.platform if save_to_repository
-
@build_list.priority = current_user.build_priority # User builds more priority than mass rebuild with zero priority
-
-
create_subject @build_list
-
end
-
-
1
def cancel
-
authorize @build_list
-
render_json :cancel
-
end
-
-
1
def publish
-
authorize @build_list
-
@build_list.publisher = current_user
-
render_json :publish
-
end
-
-
1
def reject_publish
-
authorize @build_list
-
@build_list.publisher = current_user
-
render_json :reject_publish
-
end
-
-
1
def create_container
-
authorize @build_list
-
render_json :create_container, :publish_container
-
end
-
-
1
def rerun_tests
-
authorize @build_list
-
render_json :rerun_tests
-
end
-
-
1
def publish_into_testing
-
authorize @build_list
-
@build_list.publisher = current_user
-
render_json :publish_into_testing
-
end
-
-
1
private
-
-
1
def build_list_params
-
subject_params(BuildList)
-
end
-
-
# Private: before_action hook which loads BuidList.
-
1
def load_build_list
-
@build_list = BuildList.find params[:id]
-
end
-
-
1
def render_json(action_name, action_method = nil)
-
if @build_list.try("can_#{action_name}?") && @build_list.send(action_method || action_name)
-
render_json_response @build_list, t("layout.build_lists.#{action_name}_success")
-
else
-
render_validation_error @build_list, t("layout.build_lists.#{action_name}_fail")
-
end
-
end
-
end
-
1
class Api::V1::GroupsController < Api::V1::BaseController
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:show, :projects] if APP_CONFIG['anonymous_access']
-
1
before_action :load_group, except: %i(index create)
-
-
1
def index
-
authorize :group
-
@groups = current_user.groups.paginate(paginate_params)
-
end
-
-
1
def show
-
authorize @group
-
end
-
-
1
def members
-
authorize @group
-
@members = @group.members.where('actor_id != ?', @group.owner_id)
-
.order('name').paginate(paginate_params)
-
end
-
-
1
def projects
-
authorize @group
-
render plain: @group.projects.pluck(:owner_uname, :name).map { |p| "#{p[0]}/#{p[1]}" }.join("\n")
-
end
-
-
1
def update
-
update_subject @group
-
end
-
-
1
def destroy
-
destroy_subject @group
-
end
-
-
1
def create
-
@group = current_user.own_groups.new
-
@group.assign_attributes(group_params)
-
create_subject @group
-
end
-
-
1
def add_member
-
params[:type] = 'User'
-
add_member_to_subject @group, (params[:role] || 'admin')
-
end
-
-
1
def remove_member
-
params[:type] = 'User'
-
remove_member_from_subject @group
-
end
-
-
1
def update_member
-
params[:type] = 'User'
-
update_member_in_subject @group, :actors
-
end
-
-
1
private
-
-
1
def group_params
-
subject_params(Group, @group)
-
end
-
-
# Private: before_action hook which loads Group.
-
1
def load_group
-
@group = Group.find params[:id]
-
end
-
-
end
-
1
class Api::V1::IssuesController < Api::V1::BaseController
-
1
include Api::V1::Issueable
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: %i(index group_index show) if APP_CONFIG['anonymous_access']
-
-
1
before_action :load_group, only: :group_index
-
1
before_action :load_project
-
1
skip_before_action :load_project, only: %i(all_index user_index group_index)
-
1
before_action :load_issue, only: %i(show update index)
-
-
1
def index
-
@issues = @project.issues
-
render_issues_list
-
end
-
-
1
def all_index
-
authorize :issue, :index?
-
project_ids = get_all_project_ids membered_projects.pluck(:id)
-
@issues = Issue.where(project_id: project_ids)
-
render_issues_list
-
end
-
-
1
def user_index
-
authorize :issue, :index?
-
project_ids = get_all_project_ids current_user.projects.pluck(:id)
-
@issues = Issue.where(project_id: project_ids)
-
render_issues_list
-
end
-
-
1
def group_index
-
project_ids = @group.projects.pluck(:id)
-
project_ids = membered_projects.where(id: project_ids).pluck(:id)
-
@issues = Issue.where(project_id: project_ids)
-
render_issues_list
-
end
-
-
1
def show
-
if @issue.pull_request
-
redirect_to api_v1_project_pull_request_path(@project.id, @issue.serial_id)
-
else
-
respond_to :json
-
end
-
end
-
-
1
def create
-
@issue = @project.issues.new
-
@issue.assign_attributes subject_params(Issue, @issue)
-
@issue.user = current_user
-
create_subject @issue
-
end
-
-
1
def update
-
@issue.labelings.destroy_all if params[:update_labels] && policy(@project).write?
-
if params[:issue] && status = params[:issue].delete(:status)
-
@issue.set_close(current_user) if status == 'closed'
-
@issue.set_open if status == 'open'
-
end
-
update_subject @issue
-
end
-
-
1
private
-
-
1
def render_issues_list
-
@issues = @issues.preload(:user, :assignee, :labels, :project).without_pull_requests
-
if params[:status] == 'closed'
-
@issues = @issues.closed
-
else
-
@issues = @issues.opened
-
end
-
-
if action_name == 'index' && params[:assignee].present?
-
case params[:assignee]
-
when 'none'
-
@issues = @issues.where(assigned_id: nil)
-
when '*'
-
@issues = @issues.where('issues.assigned_id IS NOT NULL')
-
else
-
@issues = @issues.where('issues.assignees_issues.uname = ?', params[:assignee])
-
end
-
end
-
-
if %w[all_index user_index group_index].include?(action_name)
-
case params[:filter]
-
when 'created'
-
@issues = @issues.where(user_id: current_user)
-
when 'all'
-
else
-
@issues = @issues.where(assignee_id: current_user)
-
end
-
else
-
@issues.where('users.uname = ?', params[:creator]) if params[:creator].present?
-
end
-
-
if params[:labels].present?
-
labels = params[:labels].split(',').map(&:strip).select(&:present?)
-
@issues = @issues.where('labels.name IN (?)', labels)
-
end
-
-
sort = params[:sort] == 'updated' ? 'issues.updated_at' : 'issues.created_at'
-
direction = params[:direction] == 'asc' ? 'ASC' : 'DESC'
-
@issues = @issues.order("#{sort} #{direction}")
-
-
@issues = @issues.where('issues.created_at >= to_timestamp(?)', params[:since]) if params[:since] =~ /\A\d+\z/
-
@issues = @issues.paginate(paginate_params)
-
-
respond_to do |format|
-
format.json { render :index }
-
end
-
end
-
-
end
-
1
class Api::V1::JobsController < Api::V1::BaseController
-
# QUEUES = %w(iso_worker_observer publish_observer rpm_worker_observer)
-
# QUEUE_CLASSES = %w(AbfWorker::IsoWorkerObserver AbfWorker::PublishObserver AbfWorker::RpmWorkerObserver)
-
1
QUEUES = %w(rpm_worker_observer)
-
1
QUEUE_CLASSES = %w(AbfWorker::RpmWorkerObserver)
-
-
1
before_action :authenticate_user!
-
1
skip_after_action :verify_authorized
-
-
1
def shift
-
job_shift_sem = Redis::Semaphore.new(:job_shift_lock)
-
job_shift_sem.lock do
-
build_lists = BuildList.scoped_to_arch(arch_ids).
-
for_status([BuildList::BUILD_PENDING, BuildList::RERUN_TESTS]).
-
for_platform(platform_ids).where(builder: nil)
-
-
if current_user.system?
-
build_lists = build_lists.where(external_nodes: ["", nil, "everything"])
-
uid = build_lists.where(mass_build_id: nil).pluck('DISTINCT user_id').sample
-
if !uid
-
uid = build_lists.pluck('DISTINCT user_id').sample
-
mass_build = true
-
else
-
mass_build = false
-
end
-
-
if uid
-
if !mass_build
-
@build_list = build_lists.where(user_id: uid, mass_build_id: nil).order(:created_at).first
-
else
-
@build_list = build_lists.where(user_id: uid).order(:created_at).first
-
end
-
end
-
else
-
tmp = build_lists.external_nodes(:owned).for_user(current_user).order(:created_at)
-
@build_list = tmp.where(mass_build_id: nil).first
-
@build_list ||= tmp.first
-
if !@build_list
-
tmp = BuildListPolicy::Scope.new(current_user, build_lists).owned.
-
external_nodes(:everything).readonly(false).order(:created_at)
-
@build_list ||= tmp.where(mass_build_id: nil).first
-
@build_list ||= tmp.first
-
end
-
end
-
set_builder
-
end
-
-
job = {
-
worker_queue: '',
-
worker_class: '',
-
:worker_args => [@build_list.abf_worker_args]
-
} if @build_list
-
render json: { job: job }.to_json
-
end
-
-
1
def statistics
-
if params[:uid].present?
-
RpmBuildNode.create(
-
id: params[:uid],
-
user_id: current_user.id,
-
system: current_user.system?,
-
worker_count: params[:worker_count],
-
busy_workers: params[:busy_workers],
-
host: params[:host].to_s,
-
query_string: params[:query_string].to_s,
-
last_build_id: params[:last_build_id].to_s
-
) rescue nil
-
end
-
head :ok
-
end
-
-
1
def status
-
if params[:key] =~ /\Aabfworker::(rpm|iso)-worker-[\d]+::live-inspector\z/
-
status = Redis.current.get(params[:key])
-
end
-
render json: { status: status }.to_json
-
end
-
-
1
def logs
-
name = params[:name]
-
if name =~ /abfworker::rpm-worker/
-
if current_user.system? || current_user.id == BuildList.where(id: name.gsub(/[^\d]/, '')).first.try(:builder_id)
-
BuildList.log_server.setex name, 15, params[:logs]
-
end
-
end
-
head :ok
-
end
-
-
1
def feedback
-
worker_queue = params[:worker_queue]
-
worker_class = params[:worker_class]
-
if QUEUES.include?(worker_queue) && QUEUE_CLASSES.include?(worker_class)
-
worker_args = (params[:worker_args] || []).first || {}
-
worker_args = worker_args.merge(feedback_from_user: current_user.id)
-
Resque.push worker_queue, 'class' => worker_class, 'args' => [worker_args]
-
head :ok
-
else
-
head 403
-
end
-
end
-
-
1
protected
-
-
1
def platform_ids
-
@platform_ids ||= begin
-
platform_types = params[:platform_types].to_s.split(',') & APP_CONFIG['distr_types']
-
platforms = params[:platforms].to_s.split(',')
-
platforms = platforms.present? ? Platform.where(name: platforms).pluck(:id) : []
-
platforms |= Platform.main.where(distrib_type: platform_types).pluck(:id) if !platform_types.empty?
-
platforms
-
end
-
end
-
-
1
def arch_ids
-
@arch_ids ||= begin
-
arches = params[:arches].to_s.split(',')
-
arches.present? ? Arch.where(name: arches).pluck(:id) : []
-
end
-
end
-
-
1
def set_builder
-
return unless @build_list
-
@build_list.builder = current_user
-
if !@build_list.valid?
-
Raven.capture_message('Invalid build list', extra: { id: @build_list.id, errors: @build_list.errors.map(&:full_message) })
-
end
-
@build_list.save(validate: false)
-
end
-
-
end
-
1
class Api::V1::MaintainersController < Api::V1::BaseController
-
1
before_action :authenticate_user! unless APP_CONFIG['anonymous_access']
-
-
1
def index
-
authorize @platform = Platform.find(params[:platform_id]), :show?
-
@maintainers = BuildList::Package.includes(:project)
-
.actual.by_platform(@platform)
-
.like_name(params[:package_name])
-
.paginate(paginate_params)
-
end
-
end
-
1
class Api::V1::PlatformsController < Api::V1::BaseController
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: :allowed
-
1
skip_before_action :authenticate_user!, only: [:show, :platforms_for_build, :members] if APP_CONFIG['anonymous_access']
-
1
before_action :load_platform, except: [:index, :allowed, :platforms_for_build, :create]
-
-
1
def allowed
-
authorize :platform
-
if request.authorization.present?
-
token, pass = *ActionController::HttpAuthentication::Basic::user_name_and_password(request)
-
end
-
if Platform.allowed?(params[:path] || '', token)
-
head :ok
-
else
-
head :forbidden
-
end
-
end
-
-
1
def index
-
authorize :platform
-
@platforms = PlatformPolicy::Scope.new(current_user, Platform).show.
-
by_type(params[:type]).paginate(paginate_params)
-
end
-
-
1
def show
-
end
-
-
1
def projects
-
render plain: @platform.projects.pluck(:owner_uname, :name).map { |p| "#{p[0]}/#{p[1]}" }.join("\n")
-
end
-
-
1
def platforms_for_build
-
authorize :platform
-
@platforms = Platform.availables_main_platforms(current_user)
-
render :index
-
end
-
-
1
def create
-
pp = params[:platform] || {}
-
owner = User.find_by(id: pp[:owner_id])
-
@platform = Platform.new(platform_params)
-
@platform.owner = owner || get_owner
-
create_subject @platform
-
end
-
-
1
def update
-
pp = params[:platform] || {}
-
owner = User.find_by(id: pp[:owner_id])
-
pp[:owner] = owner if owner
-
update_subject @platform
-
end
-
-
1
def members
-
@members = @platform.members.order('name').paginate(paginate_params)
-
end
-
-
1
def add_member
-
add_member_to_subject @platform
-
end
-
-
1
def remove_member
-
remove_member_from_subject @platform
-
end
-
-
1
def clone
-
platform_params = params[:platform] || {}
-
platform_params[:owner] = current_user
-
@cloned = @platform.full_clone(platform_params)
-
if @cloned.persisted?
-
render_json_response @platform, 'Platform has been cloned successfully'
-
else
-
render_validation_error @platform, 'Platform has not been cloned'
-
end
-
end
-
-
1
def clear
-
@platform.clear
-
render_json_response @platform, 'Platform has been cleared successfully'
-
end
-
-
1
def destroy
-
destroy_subject @platform
-
end
-
-
1
private
-
-
1
def platform_params
-
subject_params(Platform)
-
end
-
-
# Private: before_action hook which loads Platform.
-
1
def load_platform
-
authorize @platform = Platform.find(params[:id])
-
end
-
-
end
-
1
class Api::V1::ProductBuildListsController < Api::V1::BaseController
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:index, :show] if APP_CONFIG['anonymous_access']
-
-
1
before_action :load_product, only: :index
-
1
before_action :load_product_build_list, except: [:index, :create]
-
-
1
def index
-
@product_build_lists =
-
if @product
-
@product.product_build_lists
-
else
-
PlatformPolicy::Scope.new(current_user, ProductBuildList.joins(product: :platform)).show
-
end
-
@product_build_lists = @product_build_lists.joins(:product, :project, :arch)
-
@product_build_lists = @product_build_lists.recent.paginate(paginate_params)
-
end
-
-
1
def create
-
@product_build_list = ProductBuildList.new subject_params(ProductBuildList)
-
@product_build_list.project ||= @product_build_list.try(:product).try(:project)
-
@product_build_list.main_script ||= @product_build_list.try(:product).try(:main_script)
-
@product_build_list.params ||= @product_build_list.try(:product).try(:params)
-
@product_build_list.time_living ||= @product_build_list.try(:product).try(:time_living)
-
create_subject @product_build_list
-
end
-
-
1
def show
-
end
-
-
1
def update
-
params[:product_build_list] = {not_delete: (params[:product_build_list] || {})[:not_delete]}
-
update_subject @product_build_list
-
end
-
-
1
def destroy
-
destroy_subject @product_build_list
-
end
-
-
1
def cancel
-
if @product_build_list.try(:can_cancel?) && @product_build_list.cancel
-
render_json_response @product_build_list, t("layout.product_build_lists.cancel_success")
-
else
-
render_validation_error @product_build_list, t("layout.product_build_lists.cancel_fail")
-
end
-
end
-
-
1
private
-
-
# Private: before_action hook which loads ProductBuildList.
-
1
def load_product_build_list
-
authorize @product_build_list = ProductBuildList.find(params[:id])
-
end
-
-
# Private: before_action hook which loads Product.
-
1
def load_product
-
authorize @product = Product.find(params[:product_id]), :show? if params[:product_id]
-
end
-
end
-
1
class Api::V1::ProductsController < Api::V1::BaseController
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:index, :show] if APP_CONFIG['anonymous_access']
-
-
1
before_action :load_product, except: :create
-
-
1
def create
-
create_subject @product = Product.new(subject_params(Product))
-
end
-
-
1
def update
-
update_subject @product
-
end
-
-
1
def show
-
end
-
-
1
def destroy
-
destroy_subject @product
-
end
-
-
1
private
-
-
# Private: before_action hook which loads Product.
-
1
def load_product
-
authorize @product = Product.find(params[:id])
-
end
-
-
end
-
1
class Api::V1::ProjectsController < Api::V1::BaseController
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:get_id, :show, :refs_list] if APP_CONFIG['anonymous_access']
-
-
1
before_action :load_project, except: [:index, :create, :get_id]
-
-
1
def index
-
authorize :project
-
@projects = ProjectPolicy::Scope.new(current_user, Project).
-
membered.paginate(paginate_params)
-
end
-
-
1
def get_id
-
authorize @project = Project.find_by_owner_and_name!(params[:owner], params[:name])
-
end
-
-
1
def show
-
end
-
-
1
def refs_list
-
@refs = @project.repo.branches + @project.repo.tags.select{ |t| t.commit }
-
end
-
-
1
def update
-
update_subject @project
-
end
-
-
1
def destroy
-
destroy_subject @project
-
end
-
-
1
def create
-
@project = Project.new subject_params(Project)
-
p_params = params[:project] || {}
-
owner_type = %w(User Group).find{ |t| t == p_params[:owner_type] }
-
if owner_type.present?
-
@project.owner = owner_type.constantize.find_by(id: p_params[:owner_id])
-
else
-
@project.owner = nil
-
end
-
authorize @project
-
create_subject @project
-
end
-
-
1
def members
-
@members = @project.collaborators.order('uname').paginate(paginate_params)
-
end
-
-
1
def add_member
-
add_member_to_subject @project, params[:role]
-
end
-
-
1
def remove_member
-
remove_member_from_subject @project
-
end
-
-
1
def update_member
-
update_member_in_subject @project
-
end
-
-
1
def fork(is_alias = false)
-
owner = (Group.find params[:group_id] if params[:group_id].present?) || current_user
-
authorize @project, :show?
-
authorize owner, :write? if owner.is_a?(Group)
-
-
if forked = @project.fork(owner, new_name: params[:fork_name], is_alias: is_alias) and forked.valid?
-
render_json_response forked, 'Project has been forked successfully'
-
else
-
render_validation_error forked, 'Project has not been forked'
-
end
-
end
-
-
1
def alias
-
authorize @project
-
fork(true)
-
end
-
-
1
private
-
-
# Private: before_action hook which loads Project.
-
1
def load_project
-
authorize @project = Project.find(params[:id])
-
end
-
end
-
1
class Api::V1::PullRequestsController < Api::V1::BaseController
-
1
include Api::V1::Issueable
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: %i(show index group_index commits files) if APP_CONFIG['anonymous_access']
-
-
1
before_action :load_group, only: %i(group_index)
-
1
before_action :load_project, except: %i(all_index user_index)
-
1
before_action :load_issue, only: %i(show index commits files merge update)
-
1
before_action :load_pull, only: %i(show index commits files merge update)
-
-
1
def index
-
@pulls = @project.pull_requests
-
@pulls_url = api_v1_project_pull_requests_path(@project, format: :json)
-
render_pulls_list
-
end
-
-
1
def all_index
-
authorize :pull_request, :index?
-
project_ids = get_all_project_ids membered_projects.pluck(:id)
-
@pulls = PullRequest.where('pull_requests.to_project_id IN (?)', project_ids)
-
@pulls_url = api_v1_pull_requests_path format: :json
-
render_pulls_list
-
end
-
-
1
def user_index
-
authorize :pull_request, :index?
-
project_ids = get_all_project_ids current_user.projects.pluck(:id)
-
@pulls = PullRequest.where('pull_requests.to_project_id IN (?)', project_ids)
-
@pulls_url = pull_requests_api_v1_user_path format: :json
-
render_pulls_list
-
end
-
-
1
def group_index
-
project_ids = @group.projects.pluck(:id)
-
project_ids = membered_projects.where(id: project_ids).pluck(:id)
-
@pulls = PullRequest.where(to_project_id: project_ids)
-
@pulls_url = pull_requests_api_v1_group_path
-
render_pulls_list
-
end
-
-
1
def show
-
redirect_to api_v1_project_issue_path(@project.id, @issue.serial_id) and return if @pull.nil?
-
end
-
-
1
def create
-
from_project = Project.find_by(id: pull_params[:from_project_id])
-
from_project ||= @project
-
authorize from_project, :show?
-
-
@pull = @project.pull_requests.build
-
@pull.build_issue title: pull_params[:title], body: pull_params[:body]
-
@pull.from_project = from_project
-
@pull.to_ref, @pull.from_ref = pull_params[:to_ref], pull_params[:from_ref]
-
@pull.issue.assignee_id = pull_params[:assignee_id] if policy(@project).write?
-
@pull.issue.user, @pull.issue.project = current_user, @project
-
@pull.issue.new_pull_request = true
-
render_validation_error(@pull, "#{@pull.class.name} has not been created") && return unless @pull.valid?
-
-
authorize @pull
-
@pull.save # set pull id
-
@pull.reload
-
@pull.check(false) # don't make event transaction
-
if @pull.already?
-
@pull.destroy
-
error_message = I18n.t('projects.pull_requests.up_to_date', to_ref: @pull.to_ref, from_ref: @pull.from_ref)
-
render_json_response(@pull, error_message, 422)
-
else
-
@pull.send(@pull.status == 'blocked' ? 'block' : @pull.status)
-
render_json_response @pull, "#{@pull.class.name} has been created successfully"
-
end
-
end
-
-
1
def update
-
@pull = @project.pull_requests.includes(:issue).where(issues: {serial_id: params[:id]}).first
-
authorize @pull
-
-
if pull_params.present?
-
attrs = subject_params(PullRequest)
-
attrs.merge!(assignee_id: pull_params[:assignee_id]) if policy(@project).write?
-
-
if action = %w(close reopen).find{ |s| s == pull_params[:status] }
-
if @pull.send("can_#{action}?")
-
@pull.set_user_and_time current_user
-
need_check = true if action == 'reopen' && @pull.valid?
-
end
-
end
-
end
-
-
class_name = @pull.class.name
-
if @pull.issue.update(attrs)
-
@pull.send(action) if action.present?
-
@pull.check if need_check
-
render_json_response @pull, "#{class_name} has been updated successfully"
-
else
-
render_validation_error @pull, "#{class_name} has not been updated"
-
end
-
end
-
-
1
def commits
-
authorize @pull
-
@commits = @pull.repo.commits_between(@pull.to_commit, @pull.from_commit).paginate(paginate_params)
-
end
-
-
1
def files
-
authorize @pull
-
@stats = @pull.diff_stats.zip(@pull.diff).paginate(paginate_params)
-
end
-
-
1
def merge
-
authorize @pull
-
class_name = @pull.class.name
-
if @pull.merge!(current_user)
-
render_json_response @pull, "#{class_name} has been merged successfully"
-
else
-
render_validation_error @pull, "#{class_name} has not been merged"
-
end
-
end
-
-
1
private
-
-
# Private: before_action hook which loads PullRequest.
-
1
def load_pull
-
@pull = @issue.pull_request
-
authorize @pull, :show? if @pull
-
end
-
-
1
def render_pulls_list
-
@pulls = @pulls.includes(issue: [:user, :assignee])
-
if params[:status] == 'closed'
-
@pulls = @pulls.closed_or_merged
-
else
-
@pulls = @pulls.not_closed_or_merged
-
end
-
-
if action_name == 'index' && params[:assignee].present?
-
case params[:assignee]
-
when 'none'
-
@pulls = @pulls.where('issues.assigned_id IS NULL')
-
when '*'
-
@pulls = @pulls.where('issues.assigned_id IS NOT NULL')
-
else
-
@pulls = @pulls.where('assignees_issues.uname = ?', params[:assignee])
-
end
-
end
-
-
if %w[all_index user_index group_index].include?(action_name)
-
case params[:filter]
-
when 'created'
-
@pulls = @pulls.where('issues.user_id = ?', current_user.id)
-
when 'all'
-
else
-
@pulls = @pulls.where('issues.assignee_id = ?', current_user.id)
-
end
-
else
-
@pulls.where('users.uname = ?', params[:creator]) if params[:creator].present?
-
end
-
-
sort = params[:sort] == 'updated' ? 'issues.updated_at' : 'issues.created_at'
-
direction = params[:direction] == 'asc' ? 'ASC' : 'DESC'
-
@pulls = @pulls.order("#{sort} #{direction}")
-
-
@pulls = @pulls.where('issues.created_at >= to_timestamp(?)', params[:since]) if params[:since] =~ /\A\d+\z/
-
@pulls = @pulls.paginate(paginate_params)
-
-
render :index
-
end
-
-
1
def pull_params
-
@pull_params ||= params[:pull_request] || {}
-
end
-
end
-
1
class Api::V1::RepositoriesController < Api::V1::BaseController
-
1
respond_to :csv, only: :packages
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:show, :projects] if APP_CONFIG['anonymous_access']
-
1
before_action :load_repository
-
-
1
def show
-
end
-
-
1
def projects
-
@projects = @repository.projects.recent.paginate(paginate_params)
-
end
-
-
1
def update
-
update_subject @repository
-
end
-
-
1
def add_member
-
add_member_to_subject @repository
-
end
-
-
1
def remove_member
-
remove_member_from_subject @repository
-
end
-
-
1
def destroy
-
destroy_subject @repository
-
end
-
-
1
def public_key
-
if @repository.key_pair
-
render plain: @repository.key_pair.public.gsub("\r\n", "\n") + "\n"
-
else
-
render plain: ''
-
end
-
end
-
-
1
def key_pair
-
end
-
-
# Only one request per 15 minutes for each platform
-
1
def packages
-
key, now = [@repository.platform.id, :repository_packages], Time.zone.now
-
last_request = Rails.cache.read(key)
-
if last_request.present? && last_request + 15.minutes > now
-
raise Pundit::NotAuthorizedError
-
else
-
-
Rails.cache.write(key, now, expires_at: 15.minutes)
-
respond_to do |format|
-
format.csv do
-
set_csv_file_headers :packages
-
set_streaming_headers
-
-
response.status = 200
-
-
# setting the body to an enumerator, rails will iterate this enumerator
-
self.response_body = Enumerator.new do |y|
-
y << Api::V1::RepositoryPackagePresenter.csv_header.to_s
-
BuildList::Package.by_repository(@repository) do |package|
-
y << Api::V1::RepositoryPackagePresenter.new(package).to_csv_row.to_s
-
end
-
end
-
-
end
-
end
-
-
end
-
end
-
-
1
def add_repo_lock_file
-
@repository.add_repo_lock_file
-
render_json_response @repository, "'.repo.lock' file has been added to repository successfully"
-
end
-
-
1
def remove_repo_lock_file
-
@repository.remove_repo_lock_file
-
render_json_response @repository, "'.repo.lock' file has been removed from repository successfully"
-
end
-
-
1
def add_project
-
if project = Project.where(id: params[:project_id]).first
-
if policy(project).read?
-
begin
-
@repository.projects << project
-
render_json_response @repository, "Project '#{project.id}' has been added to repository successfully"
-
rescue ActiveRecord::RecordInvalid
-
render_validation_error @repository, t('flash.repository.project_not_added')
-
end
-
else
-
render_validation_error @repository, 'You have no access to read this project'
-
end
-
else
-
render_validation_error @repository, "Project has not been added to repository"
-
end
-
end
-
-
1
def remove_project
-
project_id = params[:project_id]
-
ProjectToRepository.where(project_id: project_id, repository_id: @repository.id).destroy_all
-
render_json_response @repository, "Project '#{project_id}' has been removed from repository successfully"
-
end
-
-
1
def signatures
-
key_pair = @repository.key_pair
-
key_pair.destroy if key_pair
-
key_pair = @repository.build_key_pair subject_params(Repository, KeyPair)
-
key_pair.user_id = current_user.id
-
authorize key_pair, :create?
-
if key_pair.save
-
render_json_response @repository, 'Signatures have been updated for repository successfully'
-
else
-
render_json_response @repository, error_message(key_pair, 'Signatures have not been updated for repository'), 422
-
end
-
end
-
-
1
private
-
-
# Private: before_action hook which loads Repository.
-
1
def load_repository
-
authorize @repository = Repository.find(params[:id])
-
end
-
-
end
-
1
class Api::V1::SearchController < Api::V1::BaseController
-
1
def index
-
authorize :search
-
-
search = Search.new(params[:query], current_user, paginate_params)
-
types = Search::TYPES.find{ |t| t == params[:type] } || Search::TYPES
-
@results = {}
-
[types].flatten.each do |type|
-
@results[type] = search.send(type)
-
end
-
end
-
end
-
1
class Api::V1::UsersController < Api::V1::BaseController
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:show] if APP_CONFIG['anonymous_access']
-
1
before_action :load_user, only: %i(show)
-
1
before_action :set_current_user, except: :show
-
-
1
def show
-
@user = User.opened.find params[:id] # dont show system users
-
end
-
-
1
def show_current_user
-
render :show
-
end
-
-
1
def update
-
user_params = params[:user] || {}
-
send_confirmation = if user_params.include?(:email) && user_params[:email] != @user.email
-
true
-
else
-
false
-
end
-
if @user.update_without_password(subject_params(User))
-
if send_confirmation
-
@user.confirmed_at, @user.confirmation_sent_at = nil
-
@user.send_confirmation_instructions
-
end
-
render_json_response @user, 'User has been updated successfully'
-
else
-
render_validation_error @user, "#{class_name} has not been updated"
-
end
-
end
-
-
1
def notifiers
-
if request.put?
-
if @user.notifier.update(notifier_params)
-
render_json_response @user, 'User notification settings have been updated successfully'
-
else
-
render_json_response @user, error_message(@user.notifier, 'User notification settings have not been updated'), 422
-
end
-
end
-
end
-
-
1
def tokens
-
render plain: User.pluck(:authentication_token).join("\n")
-
end
-
-
1
protected
-
-
1
def notifier_params
-
permit_params(:notifiers, *policy(SettingsNotifier).permitted_attributes)
-
end
-
-
1
def set_current_user
-
authorize @user = current_user
-
end
-
-
# Private: before_action hook which loads User.
-
1
def load_user
-
authorize @user = User.find(params[:id])
-
end
-
-
end
-
1
class ApplicationController < ActionController::Base
-
1
include StrongParams
-
1
include Pundit
-
-
SENTRY_IGNORE = [
-
1
ActionController::InvalidAuthenticityToken,
-
AbstractController::ActionNotFound
-
]
-
-
1
protect_from_forgery
-
-
1
layout :layout_by_resource
-
-
# Hack to prevent token auth on all pages except atom feed:
-
4
prepend_before_action -> { redirect_to(new_user_session_path) if params[:token] && params[:token].is_a?(String) && params[:format] != 'atom'}
-
-
1
before_action :set_locale
-
1
before_action -> { EventLog.current_controller = self },
-
only: [:create, :destroy, :open_id, :cancel, :publish, :change_visibility] # :update
-
1
before_action :banned?
-
4
after_action -> { EventLog.current_controller = nil }
-
1
after_action :verify_authorized, unless: :devise_controller?
-
1
skip_after_action :verify_authorized, only: %i(render_500 render_404)
-
1
before_action :set_raven_context
-
-
1
helper_method :get_owner
-
-
1
unless Rails.env.development?
-
1
rescue_from Exception, with: :render_500
-
1
rescue_from ActiveRecord::RecordNotFound,
-
# ActionController::RoutingError, # see: config/routes.rb:<last line>
-
# ActionController::UnknownController,
-
ActionController::UnknownFormat,
-
AbstractController::ActionNotFound, with: :render_404
-
end
-
-
1
rescue_from Pundit::NotAuthorizedError do |exception|
-
redirect_to forbidden_url, alert: t("flash.exception_message")
-
end
-
-
1
rescue_from Grit::NoSuchPathError, with: :not_found
-
-
-
1
def render_404
-
render_error 404
-
end
-
-
1
protected
-
-
# Disables access to site for banned users
-
1
def banned?
-
3
if user_signed_in? && current_user.access_locked?
-
sign_out current_user
-
flash[:error] = I18n.t('devise.failure.locked')
-
redirect_to root_path
-
end
-
end
-
-
1
def authenticate_admin!
-
authenticate_user!
-
redirect_to root_url unless current_user.admin?
-
end
-
-
# For this example, we are simply using token authentication
-
# via parameters. However, anyone could use Rails's token
-
# authentication features to get the token from a header.
-
1
def authenticate_user!
-
3
if user = find_user_by_token
-
# Notice we are passing store false, so the user is not
-
# actually stored in the session and a token is needed
-
# for every request. If you want the token to work as a
-
# sign in token, you can simply remove store: false.
-
sign_in user, store: false
-
else
-
3
super
-
end
-
end
-
-
1
def authenticate_user
-
3
if user = find_user_by_token
-
sign_in user, store: false
-
end
-
end
-
-
1
def find_user_by_token
-
6
user_token = params[:authentication_token].presence
-
6
if user_token.blank? && request.authorization.present?
-
token, pass = *ActionController::HttpAuthentication::Basic::user_name_and_password(request)
-
user_token = token if pass.blank?
-
end
-
6
user = user_token && User.find_by_authentication_token(user_token.to_s)
-
end
-
-
1
def render_500(e)
-
#check for exceptions Sentry ignores by default and exclude them from manual Sentry notification
-
if Rails.env.production? && !SENTRY_IGNORE.include?(e.class)
-
Raven.capture_exception(e)
-
end
-
Rails.logger.error e.backtrace.inspect
-
Rails.logger.error e.message
-
render_error 500
-
end
-
-
1
def render_error(status)
-
respond_to do |format|
-
format.json { render json: {status: status, message: t("flash.#{status}_message")}.to_json, status: status }
-
format.all { render file: Rails.root.join("public/#{status}.html"), status: status,
-
alert: t("flash.#{status}_message"), layout: false, content_type: 'text/html' }
-
end
-
end
-
-
# Helper method for all controllers
-
1
def permit_params(param_name, *accessible)
-
(params[param_name] || ActionController::Parameters.new).permit(*accessible.flatten).to_h
-
end
-
-
1
def set_locale
-
3
I18n.locale = check_locale( get_user_locale ||
-
(request.env['HTTP_ACCEPT_LANGUAGE'] ? request.env['HTTP_ACCEPT_LANGUAGE'][0,2].downcase : nil ))
-
end
-
-
1
def get_user_locale
-
3
user_signed_in? ? current_user.language : nil
-
end
-
-
1
def check_locale(locale)
-
3
User::LANGUAGES.include?(locale.to_s) ? locale : :en
-
end
-
-
1
def get_owner
-
if self.class.method_defined? :parent
-
if parent and (parent.is_a? User or parent.is_a? Group)
-
return parent
-
else
-
return current_user
-
end
-
else
-
params['user_id'] && User.find(params['user_id']) ||
-
params['group_id'] && Group.find(params['group_id']) || current_user
-
end
-
end
-
-
1
def layout_by_resource
-
1
if devise_controller?
-
"sessions"
-
else
-
1
"application"
-
end
-
end
-
-
1
def not_found
-
raise ActionController::RoutingError.new('Not Found')
-
end
-
-
1
def current_page
-
params[:page] = 1 if params[:page].to_i < 1
-
-
params[:page]
-
end
-
-
1
def set_raven_context
-
3
Raven.user_context(email: current_user.try(:email), id: current_user.try(:id))
-
3
Raven.extra_context(params: params.to_unsafe_h, url: request.url)
-
end
-
end
-
1
class AutocompletesController < ApplicationController
-
1
before_action :authenticate_user!
-
1
skip_after_action :verify_authorized
-
-
1
def autocomplete_user_uname
-
results = User.opened.search_like(params[:query]).search_order.limit(5)
-
render json: results.map{ |u| { id: u.id, name: u.uname } }
-
end
-
-
1
def autocomplete_user_or_group
-
results << User.opened.search_like(params[:query]).search_order.limit(5).pluck(:uname)
-
results << Group.search_like(params[:query]).search_order.limit(5).pluck(:uname)
-
render json: results.flatten.sort.map{ |r| { id: r, name: r } }
-
end
-
-
1
def autocomplete_extra_build_list
-
bl = BuildListPolicy::Scope.new(current_user, BuildList).read.
-
for_extra_build_lists(params[:term], save_to_platform).first
-
results << { :id => bl.id,
-
:value => bl.id,
-
:label => "#{bl.id} (#{bl.project.name} - #{bl.arch.name})",
-
:path => build_list_path(bl)
-
} if bl
-
render json: results.to_json
-
end
-
-
1
def autocomplete_extra_mass_build
-
mb = MassBuild.where(id: params[:term]).first
-
results << {
-
id: mb.id,
-
value: mb.id,
-
label: "#{mb.id} - #{mb.name}",
-
path: platform_mass_build_path(mb.save_to_platform, mb)
-
} if mb && policy(mb).show?
-
render json: results.to_json
-
end
-
-
1
def autocomplete_extra_repositories
-
# Only personal and build for platform repositories can be attached to the build
-
platforms = PlatformPolicy::Scope.new(current_user, Platform).show.
-
includes(:repositories).search_like(params[:term]).search_order.limit(5).
-
where("platforms.platform_type = 'personal' OR platforms.id = ?", params[:build_for_platform_id])
-
platforms.each do |platform|
-
platform.repositories.each do |repository|
-
results <<
-
{
-
id: repository.id,
-
platform_name: platform.name,
-
repository_name: repository.name,
-
label: "#{platform.name}/#{repository.name}",
-
path: platform_repository_path(platform, repository)
-
}
-
end
-
end if save_to_platform.personal?
-
render json: results.to_json
-
end
-
-
1
protected
-
-
1
def save_to_platform
-
@save_to_platform ||= Platform.find_cached(params[:platform_id])
-
end
-
-
1
def results
-
@results ||= []
-
end
-
-
end
-
1
module Api
-
1
module V1
-
1
module Issueable
-
1
extend ActiveSupport::Concern
-
-
1
protected
-
-
# Private: before_action hook which loads Group.
-
1
def load_group
-
authorize @group = Group.find(params[:id]), :show?
-
end
-
-
# Private: before_action hook which loads Project.
-
1
def load_project
-
authorize @project = Project.find(params[:project_id]), :show?
-
end
-
-
# Private: before_action hook which loads Issue.
-
1
def load_issue
-
authorize @issue = @project.issues.find_by!(serial_id: params[:id]), :show?
-
end
-
-
# Private: Get membered projects.
-
#
-
# Returns the ActiveRecord::Relation instance.
-
1
def membered_projects
-
@membered_projects ||= ProjectPolicy::Scope.new(current_user, Project).membered
-
end
-
-
# Private: Get project ids which available for current user.
-
#
-
# Returns the Array of project ids.
-
1
def get_all_project_ids(default_project_ids)
-
project_ids = []
-
if %w(created all).include? params[:filter]
-
# add own issues
-
project_ids = Project.opened.joins(:issues).
-
where(issues: {user_id: current_user.id}).
-
pluck('projects.id')
-
end
-
project_ids | default_project_ids
-
end
-
end
-
end
-
end
-
1
module StrongParams
-
1
extend ActiveSupport::Concern
-
-
1
protected
-
-
1
def permit_params(param_name, *accessible)
-
[param_name].flatten.inject(params.dup) do |pp, name|
-
pp = pp[name] || ActionController::Parameters.new
-
end.permit(*accessible.flatten)
-
end
-
-
-
1
def subject_params(subject_class, subject = nil)
-
permit_params(subject_class.name.underscore.to_sym, *policy(subject || subject_class).permitted_attributes)
-
end
-
end
-
1
class Groups::BaseController < ApplicationController
-
1
before_action :authenticate_user!
-
1
before_action :find_group
-
-
1
protected
-
-
# Private: before_action hook which loads Group.
-
1
def find_group
-
if group_id = params[:uname] || params[:group_id] || params[:id]
-
@group = Group.find_by_insensitive_uname! group_id
-
end
-
end
-
end
-
1
class Groups::MembersController < Groups::BaseController
-
1
before_action -> { authorize @group, :manage_members? }
-
-
1
def index
-
@members = @group.members.order(:uname) - [@group.owner]
-
end
-
-
1
def update
-
raise Pundit::NotAuthorizedError if @group.owner_id.to_s == params[:member_id]
-
-
relation = @group.actors.where(actor_id: params[:member_id], actor_type: 'User').first
-
relation ||= @group.actors.build(actor_id: params[:member_id], actor_type: 'User')
-
relation.role = params[:role]
-
relation.save!
-
-
flash[:notice] = t("flash.members.successfully_changed")
-
redirect_to group_members_path(@group)
-
end
-
-
1
def remove
-
User.where(id: params[:members]).each do |user|
-
@group.remove_member(user)
-
end
-
redirect_to group_members_path(@group)
-
end
-
-
1
def add
-
@user = User.find_by(id: params[:member_id])
-
if !@user
-
flash[:error] = t("flash.collaborators.wrong_user", uname: params[:user_uname])
-
elsif @group.add_member(@user, params[:role])
-
flash[:notice] = t("flash.members.successfully_added")
-
else
-
flash[:error] = t("flash.members.error_in_adding")
-
end
-
redirect_to group_members_path(@group)
-
end
-
end
-
1
class Groups::ProfileController < Groups::BaseController
-
1
include AvatarHelper
-
1
include PaginateHelper
-
-
1
skip_before_action :authenticate_user!, only: :show if APP_CONFIG['anonymous_access']
-
-
1
def index
-
authorize :group
-
@groups = current_user.groups.paginate(page: params[:group_page]) # accessible_by(current_ability)
-
@groups = @groups.search_like(params[:query]) if params[:query].present?
-
end
-
-
1
def show
-
authorize @group
-
respond_to do |format|
-
format.html do
-
@members = @group.members.order(:uname)
-
end
-
format.json do
-
@projects = @group.own_projects.search_like(params[:term]).recent
-
case params[:visibility]
-
when 'open'
-
@projects = @projects.opened
-
when 'hidden'
-
@projects = @projects.by_visibilities('hidden')
-
@projects = @projects.none unless policy(@group).reader?
-
else
-
@projects = @projects.opened unless policy(@group).reader?
-
end
-
@total_items = @projects.count
-
@projects = @projects.paginate(paginate_params)
-
render 'users/profile/show'
-
end
-
end
-
end
-
-
1
def new
-
authorize @group = current_user.own_groups.build
-
end
-
-
1
def edit
-
authorize @group
-
end
-
-
1
def create
-
@group = current_user.own_groups.new
-
@group.assign_attributes(group_params)
-
authorize @group
-
if @group.save
-
flash[:notice] = t('flash.group.saved')
-
redirect_to group_path(@group)
-
else
-
flash[:error] = t('flash.group.save_error')
-
flash[:warning] = @group.errors.map(&:full_message).join('. ')
-
render action: :new
-
end
-
end
-
-
1
def update
-
authorize @group
-
if @group.update(group_params)
-
update_avatar(@group, params)
-
flash[:notice] = t('flash.group.saved')
-
redirect_to group_path(@group)
-
else
-
flash[:error] = t('flash.group.save_error')
-
render action: :edit
-
end
-
end
-
-
1
def destroy
-
authorize @group
-
@group.destroy
-
flash[:notice] = t("flash.group.destroyed")
-
redirect_to groups_path
-
end
-
-
1
def remove_user
-
authorize @group
-
Relation.by_actor(current_user).by_target(@group).destroy_all
-
redirect_to groups_path
-
end
-
-
1
protected
-
-
1
def group_params
-
subject_params(Group, @group)
-
end
-
-
1
def paginate_projects(page)
-
@projects.paginate(page: (page>0 ? page : nil), per_page: 24)
-
end
-
end
-
1
class HomeController < ApplicationController
-
1
before_action :authenticate_user!, except: [:root]
-
1
skip_after_action :verify_authorized
-
-
1
def root
-
respond_to do |format|
-
format.html { render 'pages/tour/abf-tour-project-description-1' }
-
end
-
end
-
-
1
def activity(is_my_activity = false)
-
@filter = t('feed_menu').has_key?(params[:filter].try(:to_sym)) ? params[:filter].to_sym : :all
-
@activity_feeds = current_user.activity_feeds
-
.by_project_name(params[:project_name_filter])
-
.by_owner_uname(params[:owner_filter])
-
@activity_feeds = @activity_feeds.where(kind: "ActivityFeed::#{@filter.upcase}".constantize) unless @filter == :all
-
@activity_feeds = @activity_feeds.where(user_id: current_user) if @own_filter == :created
-
@activity_feeds = @activity_feeds.where.not(user_id: current_user) if @own_filter == :not_created
-
-
@activity_feeds = if is_my_activity
-
@activity_feeds.where(creator_id: current_user)
-
else
-
@activity_feeds.where.not(creator_id: current_user)
-
end
-
-
@activity_feeds = @activity_feeds.paginate page: current_page
-
-
respond_to do |format|
-
format.html { render 'activity' }
-
format.json { render 'activity' }
-
format.atom
-
end
-
end
-
-
1
def own_activity
-
activity(true)
-
end
-
-
1
def issues
-
@created_issues = current_user.issues
-
@assigned_issues = Issue.where(assignee_id: current_user.id)
-
@all_issues = ProjectPolicy::Scope.new(current_user, Issue).membered.distinct.joins(:project)
-
-
@created_issues, @assigned_issues, @all_issues =
-
if action_name == 'issues'
-
[@created_issues.without_pull_requests,
-
@assigned_issues.without_pull_requests,
-
@all_issues.without_pull_requests]
-
else
-
[@created_issues.joins(:pull_request),
-
@assigned_issues.joins(:pull_request),
-
@all_issues.joins(:pull_request)]
-
end
-
-
case params[:filter]
-
when 'created'
-
@issues = @created_issues
-
when 'assigned'
-
@issues = @assigned_issues
-
else
-
params[:filter] = 'all' # default
-
@issues = @all_issues
-
end
-
@filter = params[:filter]
-
@opened_issues, @closed_issues = @issues.not_closed_or_merged, @issues.closed_or_merged
-
-
@status = params[:status] == 'closed' ? :closed : :open
-
@issues = @issues.send( (@status == :closed) ? :closed_or_merged : :not_closed_or_merged )
-
-
@sort = params[:sort] == 'updated' ? :updated : :created
-
@direction = params[:direction] == 'asc' ? :asc : :desc
-
@issues = @issues.order("issues.#{@sort}_at #{@direction}")
-
.includes(:assignee, :user, :pull_request).distinct
-
.paginate page: current_page
-
-
respond_to do |format|
-
format.html { render 'activity' }
-
format.json { render 'issues' }
-
end
-
end
-
-
1
def pull_requests
-
issues
-
end
-
-
1
def get_owners_list
-
if params[:term].present?
-
users = User.opened.search_like(params[:term]).first(5)
-
groups = Group.opened.search_like(params[:term]).first(5)
-
@owners = users | groups
-
-
end
-
respond_to do |format|
-
format.json {}
-
end
-
end
-
-
1
def get_project_names_list
-
if params[:term].present?
-
@projects = ProjectPolicy::Scope.new(current_user, Project).membered
-
-
@projects = @projects.where(owner_uname: params[:owner_uname]) if params[:owner_uname].present?
-
@projects = @projects.by_name("%#{params[:term]}%")
-
.distinct
-
.pluck(:name)
-
.first(10)
-
end
-
respond_to do |format|
-
format.json {}
-
end
-
end
-
end
-
1
class PagesController < ApplicationController
-
1
skip_after_action :verify_authorized
-
-
1
def tour_inside
-
@entries = case params[:id]
-
when 'builds'
-
%w(repo builds monitoring)
-
when 'sources'
-
%w(source history annotation edit)
-
when 'projects'
-
%w(control git tracker)
-
end
-
render "pages/tour/tour-inside"
-
end
-
-
1
def forbidden
-
end
-
-
1
def tos
-
end
-
-
end
-
1
class Platforms::BaseController < ApplicationController
-
1
before_action :load_platform
-
-
1
protected
-
-
1
def load_platform
-
return unless params[:platform_id]
-
authorize @platform = Platform.find_cached(params[:platform_id]), :show?
-
end
-
-
end
-
1
class Platforms::ContentsController < Platforms::BaseController
-
1
include PaginateHelper
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: :index if APP_CONFIG['anonymous_access']
-
-
1
def index
-
respond_to do |format|
-
format.html
-
format.json do
-
@path = params[:path].to_s
-
@term = params[:term]
-
-
@contents = PlatformContent.find_by_platform(@platform, @path, @term)
-
@total_items = @contents.count
-
@contents = @contents.paginate(paginate_params)
-
end
-
end
-
-
end
-
-
1
def remove_file
-
authorize @platform
-
PlatformContent.remove_file(@platform, params[:path])
-
head :ok
-
end
-
-
end
-
1
class Platforms::KeyPairsController < Platforms::BaseController
-
1
before_action :authenticate_user!
-
-
1
def index
-
@key_pair = KeyPair.new
-
end
-
-
1
def create
-
@key_pair = KeyPair.new subject_params(KeyPair)
-
@key_pair.user_id = current_user.id
-
authorize @key_pair
-
if @key_pair.save
-
flash[:notice] = t('flash.key_pairs.saved')
-
redirect_to platform_key_pairs_path(@key_pair.repository.platform) and return
-
else
-
flash[:error] = t('flash.key_pairs.save_error')
-
end
-
render :index
-
end
-
-
1
def destroy
-
authorize @key_pair = @platform.key_pairs.find(params[:id])
-
if @key_pair.destroy
-
flash[:notice] = t('flash.key_pairs.destroyed')
-
else
-
flash[:error] = t('flash.key_pairs.destroy_error')
-
end
-
-
redirect_to platform_key_pairs_path(@key_pair.repository.platform)
-
end
-
end
-
1
class Platforms::MaintainersController < Platforms::BaseController
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:index] if APP_CONFIG['anonymous_access']
-
-
1
def index
-
@maintainer = BuildList::Package.new(build_list_package_params)
-
@packages = @platform.packages.actual.like_name(@maintainer.name)
-
@projects = @platform.projects.joins(:packages).merge( @packages ).
-
includes(:maintainer).group('projects.id').reorder(:name).paginate(page: params[:page])
-
@packages = @packages.where(project_id: @projects.map(&:id)).group_by(&:project_id)
-
end
-
-
1
def build_list_package_params
-
permit_params :build_list_package, :name
-
end
-
end
-
1
class Platforms::MassBuildsController < Platforms::BaseController
-
1
include DatatableHelper
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:index, :get_list] if APP_CONFIG['anonymous_access']
-
-
1
before_action :find_mass_build, only: %i(show publish cancel get_list show_fail_reason)
-
-
1
def new
-
if params[:mass_build_id].present?
-
@mass_build = @platform.mass_builds.find(params[:mass_build_id]).dup
-
@mass_build.arches = Arch.where(name: @mass_build.arch_names.split(', ')).pluck(:id)
-
end
-
authorize @mass_build ||= @platform.mass_builds.build
-
@mass_build.arches ||= @platform.platform_arch_settings.by_default.pluck(:arch_id)
-
@mass_build.repositories ||= []
-
@mass_build.arches.map!(&:to_s)
-
end
-
-
1
def show
-
authorize @platform.mass_builds.find(params[:id])
-
end
-
-
1
def create
-
@mass_build = @platform.mass_builds.build(subject_params(MassBuild))
-
@mass_build.user = current_user
-
@mass_build.arches = params[:arches] || []
-
@mass_build.repositories ||= params[:repositories] || []
-
-
authorize @mass_build
-
if @mass_build.save
-
redirect_to(platform_mass_builds_path(@platform), notice: t("flash.platform.build_all_success"))
-
else
-
flash[:warning] = @mass_build.errors.map(&:full_message).join('. ')
-
flash[:error] = t('flash.platform.build_all_error')
-
render action: :new
-
end
-
end
-
-
1
def publish
-
if params[:status] == 'test_failed'
-
@mass_build.publish_test_failed_builds current_user
-
else
-
@mass_build.publish_success_builds current_user
-
end
-
redirect_to(platform_mass_builds_path(@mass_build.save_to_platform), notice: t("flash.platform.publish_success"))
-
end
-
-
1
def index
-
@mass_build = MassBuild.new(params[:mass_build])
-
@mass_builds = @platform.mass_builds.search_like(@mass_build.description).
-
order(id: :desc).paginate(page: params[:page])
-
end
-
-
1
def cancel
-
@mass_build.cancel_all
-
flash[:notice] = t("flash.platform.cancel_mass_build")
-
redirect_to platform_mass_builds_path(@mass_build.save_to_platform)
-
end
-
-
1
def get_list
-
text =
-
case params[:kind]
-
when 'failed_builds_list', 'tests_failed_builds_list', 'success_builds_list'
-
@mass_build.send "generate_#{params[:kind]}"
-
when 'projects_list', 'missed_projects_list'
-
@mass_build.send params[:kind]
-
end
-
render plain: text
-
end
-
-
1
def show_fail_reason
-
respond_to do |format|
-
format.html {
-
@build_lists = @mass_build.build_lists.where(status: BuildList::BUILD_ERROR).page(params[:page])
-
data = @build_lists.pluck(:id, :project_id, :arch_id, :fail_reason)
-
arches = {}
-
Arch.all.map do |arch|
-
arches[arch.id] = arch.name
-
end
-
projects = {}
-
@items = data.map do |item|
-
if projects[item[1]]
-
item[1] = projects[item[1]]
-
else
-
project_name_with_owner = Project.find(item[1]).name_with_owner
-
projects[item[1]] = project_name_with_owner
-
item[1] = project_name_with_owner
-
end
-
item[2] = arches[item[2]]
-
item
-
end
-
}
-
format.csv {
-
log_name = params[:csv][:log_name].presence || 'script_output.log'
-
headers.delete("Content-Length")
-
headers["Cache-Control"] = "no-cache"
-
headers["Content-Type"] = "text/csv"
-
headers["Content-Disposition"] = "attachment; filename=\"mass_build_#{@mass_build.id}_failures.csv\""
-
headers["X-Accel-Buffering"] = "no"
-
-
self.response_body = Enumerator.new do |y|
-
@mass_build.build_lists.includes(:project, :arch).find_each.lazy.each do |bl|
-
log = bl.results.select { |x| x['file_name'] == log_name }.last
-
line = CSV.generate_line([
-
bl.id,
-
BuildList::HUMAN_STATUSES[bl.status].to_s,
-
bl.project.name_with_owner,
-
bl.arch.name,
-
bl.fail_reason.presence || 'Empty',
-
log.present? ? "http://file-store.rosalinux.ru/api/v1/file_stores/#{log['sha1']}.log?show=true" : ''
-
], col_sep: ';;')
-
y << line
-
end
-
end
-
}
-
end
-
end
-
-
1
private
-
-
# Private: before_action hook which loads MassBuild.
-
1
def find_mass_build
-
authorize @mass_build = @platform.mass_builds.find(params[:id])
-
end
-
end
-
1
class Platforms::PlatformsController < Platforms::BaseController
-
1
include FileStoreHelper
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:advisories, :members, :show] if APP_CONFIG['anonymous_access']
-
-
1
def index
-
authorize :platform
-
respond_to do |format|
-
format.html {}
-
-
format.json {
-
@platforms = PlatformPolicy::Scope.new(current_user, Platform).related
-
@platforms_count = @platforms.count
-
@platforms = @platforms.paginate(page: current_page, per_page: Platform.per_page)
-
}
-
end
-
end
-
-
1
def show
-
end
-
-
1
def new
-
authorize @platform = Platform.new
-
@admin_uname = current_user.uname
-
@admin_id = current_user.id
-
end
-
-
1
def edit
-
authorize @platform
-
@admin_id = @platform.owner.id
-
@admin_uname = @platform.owner.uname
-
end
-
-
1
def create
-
authorize @platform = Platform.new(platform_params)
-
@admin_id = params[:admin_id]
-
@admin_uname = params[:admin_uname]
-
# FIXME: do not allow manipulate owner model, only platforms onwer_id and onwer_type
-
@platform.owner = @admin_id.blank? ? get_owner : User.find(@admin_id)
-
-
if @platform.save
-
flash[:notice] = I18n.t("flash.platform.created")
-
redirect_to @platform
-
else
-
flash[:error] = I18n.t("flash.platform.create_error")
-
render action: :new
-
end
-
end
-
-
1
def update
-
authorize @platform
-
@admin_id = params[:admin_id]
-
@admin_uname = params[:admin_uname]
-
-
pp = platform_params
-
pp[:owner] = User.find(@admin_id) if @admin_id.present?
-
-
respond_to do |format|
-
format.html do
-
if @platform.update(pp)
-
flash[:notice] = I18n.t("flash.platform.saved")
-
redirect_to @platform
-
else
-
flash[:error] = I18n.t("flash.platform.save_error")
-
render action: :edit
-
end
-
end
-
format.json do
-
if @platform.update(pp)
-
render json: { notice: I18n.t("flash.platform.saved") }.to_json
-
else
-
render json: { error: I18n.t("flash.platform.save_error") }.to_json, status: 422
-
end
-
end
-
end
-
end
-
-
1
def regenerate_metadata
-
authorize @platform
-
if @platform.regenerate
-
flash[:notice] = I18n.t('flash.platform.saved')
-
else
-
flash[:error] = I18n.t('flash.platform.save_error')
-
end
-
redirect_to edit_platform_path(@platform)
-
end
-
-
1
def change_visibility
-
authorize @platform
-
if @platform.change_visibility
-
flash[:notice] = I18n.t("flash.platform.saved")
-
redirect_to @platform
-
else
-
flash[:error] = I18n.t("flash.platform.save_error")
-
flash[:warning] = @platform.errors.map(&:full_message).join('. ')
-
render action: :edit
-
end
-
end
-
-
1
def clone
-
authorize @platform
-
@cloned = Platform.new
-
@cloned.name = @platform.name + "_clone"
-
@cloned.description = @platform.description + "_clone"
-
end
-
-
1
def make_clone
-
authorize @platform
-
@cloned = @platform.full_clone platform_params.merge(owner: current_user)
-
if @cloned.persisted?
-
flash[:notice] = I18n.t("flash.platform.clone_success")
-
redirect_to @cloned
-
else
-
flash[:error] = @cloned.errors.map(&:full_message).join('. ')
-
render 'clone'
-
end
-
end
-
-
1
def destroy
-
authorize @platform
-
@platform.destroy # later with resque
-
flash[:notice] = t("flash.platform.destroyed")
-
redirect_to platforms_path
-
end
-
-
1
def members
-
authorize @platform
-
@members = @platform.members.order(:uname)
-
end
-
-
1
def remove_members
-
authorize @platform
-
User.where(id: params[:members]).each do |user|
-
@platform.remove_member(user)
-
end
-
redirect_to members_platform_path(@platform)
-
end
-
-
1
def add_member
-
authorize @platform
-
member = User.find_by(id: params[:member_id])
-
if !member
-
flash[:error] = t("flash.collaborators.wrong_user", uname: params[:member_id])
-
elsif @platform.add_member(member)
-
flash[:notice] = t('flash.platform.members.successfully_added', name: member.uname)
-
else
-
flash[:error] = t('flash.platform.members.error_in_adding', name: member.uname)
-
end
-
redirect_to members_platform_url(@platform)
-
end
-
-
1
def advisories
-
authorize @platform
-
@advisories = @platform.advisories.paginate(page: params[:page])
-
end
-
-
1
def clear
-
authorize @platform
-
@platform.clear
-
flash[:notice] = t('flash.repository.clear')
-
redirect_to edit_platform_path(@platform)
-
end
-
-
1
private
-
-
1
def platform_params
-
subject_params(Platform)
-
end
-
-
# Private: before_action hook which loads Platform.
-
1
def load_platform
-
authorize @platform = Platform.find_cached(params[:id]), :show? if params[:id]
-
end
-
-
end
-
1
class Platforms::ProductBuildListsController < Platforms::BaseController
-
1
include FileStoreHelper
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:index, :show, :log] if APP_CONFIG['anonymous_access']
-
1
before_action :redirect_to_full_path_if_short_url, only: [:show, :update]
-
-
1
before_action :load_product, except: :index
-
1
before_action :load_product_build_list, except: [:index, :new, :create]
-
-
1
def new
-
@product_build_list = @product.product_build_lists.new
-
@product_build_list.params = @product.params
-
@product_build_list.main_script = @product.main_script
-
@product_build_list.time_living = @product.time_living
-
@product_build_list.project_version = @product.project_version
-
@product_build_list.project = @product.project
-
unless @product_build_list.project
-
flash[:error] = t('flash.product_build_list.no_project')
-
redirect_to edit_platform_product_path(@platform, @product)
-
end
-
end
-
-
1
def show
-
end
-
-
1
def update
-
@product_build_list.update(not_delete: (params[:product_build_list] || {})[:not_delete])
-
render :show
-
end
-
-
1
def cancel
-
flash[:notice] = if @product_build_list.cancel
-
t('layout.build_lists.will_be_canceled')
-
else
-
t('layout.build_lists.cancel_fail')
-
end
-
redirect_back(fallback_location: platform_product_product_build_list_path(
-
id: @product_build_list.id,
-
product_id: @product_build_list.product.id,
-
platform_id: @product_build_list.product.platform_id
-
)
-
)
-
end
-
-
1
def log
-
worker_log = @product_build_list.abf_worker_log
-
render json: {
-
log: (Pygments.highlight(worker_log, lexer: 'sh') rescue worker_log),
-
building: @product_build_list.build_started?
-
}
-
end
-
-
1
def create
-
pbl = @product.product_build_lists.new product_build_list_params
-
pbl.project = @product.project
-
pbl.user = current_user
-
pbl.base_url = "http://#{request.host_with_port}"
-
-
authorize pbl
-
if pbl.save
-
flash[:notice] = t('flash.product.build_started')
-
redirect_to [@platform, @product]
-
else
-
flash[:error] = t('flash.product.build_error')
-
@product_build_list = pbl
-
render action: :new
-
end
-
end
-
-
1
def destroy
-
if @product_build_list.destroy
-
flash[:notice] = t('flash.product_build_list.delete')
-
else
-
flash[:error] = t('flash.product_build_list.delete_error')
-
end
-
redirect_to [@platform, @product]
-
end
-
-
1
def index
-
authorize :product_build_list
-
@product_build_list = ProductBuildList.new(product_build_list_params)
-
@product_build_list.status = nil if params[:product_build_list].try(:[], :status).blank?
-
@product_build_lists = @platform.product_build_lists if @platform
-
@product_build_lists ||= PlatformPolicy::Scope.new(current_user, ProductBuildList.joins(product: :platform)).show
-
if @product_build_list.product_id.present?
-
@product_build_lists = @product_build_lists.where(id: @product_build_list.product_id)
-
else
-
@product_build_lists = @product_build_lists.
-
scoped_to_product_name(@product_build_list.product_name).
-
for_status(@product_build_list.status)
-
end
-
@product_build_lists = @product_build_lists.
-
includes(:project, product: :platform).
-
recent.paginate(page: current_page)
-
@build_server_status = AbfWorkerStatusPresenter.new.products_status
-
end
-
-
1
protected
-
-
1
def product_build_list_params
-
subject_params(ProductBuildList)
-
end
-
-
1
def redirect_to_full_path_if_short_url
-
if params[:platform_id].blank? || params[:product_id].blank?
-
pbl = ProductBuildList.find params[:id]
-
product, platform = pbl.product, pbl.product.platform
-
redirect_to platform_product_product_build_list_path(platform, product, pbl)
-
end
-
end
-
-
# Private: before_action hook which loads ProductBuildList.
-
1
def load_product_build_list
-
authorize @product_build_list = ProductBuildList.find(params[:id])
-
end
-
-
# Private: before_action hook which loads Product.
-
1
def load_product
-
authorize @product = Product.find(params[:product_id]), :show? if params[:product_id]
-
end
-
-
end
-
1
class Platforms::ProductsController < Platforms::BaseController
-
1
include GitHelper
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:index, :show] if APP_CONFIG['anonymous_access']
-
-
1
before_action :load_product, except: %i(index new create autocomplete_project)
-
-
1
def index
-
authorize @platform.products.new
-
@products = @platform.products.paginate(page: params[:page])
-
end
-
-
1
def new
-
authorize @product = @platform.products.new
-
end
-
-
1
def edit
-
end
-
-
1
def create
-
authorize @product = @platform.products.build(product_params)
-
if @product.save
-
flash[:notice] = t('flash.product.saved')
-
redirect_to platform_product_path(@platform, @product)
-
else
-
flash[:error] = t('flash.product.save_error')
-
flash[:warning] = @product.errors.map(&:full_message).join('. ')
-
render action: :new
-
end
-
end
-
-
1
def update
-
if @product.update(product_params)
-
flash[:notice] = t('flash.product.saved')
-
redirect_to platform_product_path(@platform, @product)
-
else
-
flash[:error] = t('flash.product.save_error')
-
flash[:warning] = @product.errors.map(&:full_message).join('. ')
-
render action: "edit"
-
end
-
end
-
-
1
def show
-
@product_build_lists = @product.product_build_lists.default_order.
-
paginate(page: params[:page])
-
end
-
-
1
def destroy
-
@product.destroy
-
flash[:notice] = t("flash.product.destroyed")
-
redirect_to platform_products_path(@platform)
-
end
-
-
1
def autocomplete_project
-
authorize :project
-
@items = ProjectPolicy::Scope.new(current_user, Project).membered.
-
by_owner_and_name(params[:query]).limit(20)
-
#items.select! {|e| e.repo.branches.count > 0}
-
end
-
-
1
private
-
-
1
def product_params
-
subject_params(Product)
-
end
-
-
# Private: before_action hook which loads Product.
-
1
def load_product
-
authorize @product = Product.find(params[:id])
-
end
-
-
end
-
1
class Platforms::RepositoriesController < Platforms::BaseController
-
1
include DatatableHelper
-
1
include FileStoreHelper
-
1
include RepositoriesHelper
-
1
include PaginateHelper
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:index, :show, :projects_list] if APP_CONFIG['anonymous_access']
-
-
1
before_action :load_repository, except: [:index, :create, :new]
-
1
before_action :set_members, only: [:edit, :update]
-
1
before_action -> { @repository = @platform.repositories.find(params[:id]) if params[:id] }
-
-
1
def index
-
@repositories = @platform.repositories
-
@repositories = Repository.custom_sort(@repositories).paginate(page: current_page)
-
end
-
-
1
def show
-
params[:per_page] = 30
-
end
-
-
1
def edit
-
end
-
-
1
def update
-
authorize @repository
-
if @repository.update(repository_params)
-
flash[:notice] = I18n.t("flash.repository.updated")
-
redirect_to platform_repository_path(@platform, @repository)
-
else
-
flash[:error] = I18n.t("flash.repository.update_error")
-
flash[:warning] = @repository.errors.map(&:full_message).join('. ')
-
render action: :edit
-
end
-
end
-
-
1
def remove_members
-
User.where(id: params[:members]).find_each do |user|
-
@repository.remove_member(user)
-
end
-
redirect_to edit_platform_repository_path(@platform, @repository)
-
end
-
-
1
def add_member
-
if member = User.find_by(id: params[:member_id])
-
if @repository.add_member(member)
-
flash[:notice] = t('flash.repository.members.successfully_added', name: member.uname)
-
else
-
flash[:error] = t('flash.repository.members.error_in_adding', name: member.uname)
-
end
-
end
-
redirect_to edit_platform_repository_path(@platform, @repository)
-
end
-
-
1
def new
-
authorize @repository = @platform.repositories.new
-
@platform_id = params[:platform_id]
-
end
-
-
1
def destroy
-
authorize @repository
-
@repository.destroy
-
-
flash[:notice] = t("flash.repository.destroyed")
-
redirect_to platform_repositories_path(@repository.platform)
-
end
-
-
1
def create
-
authorize @repository = @platform.repositories.build(repository_params)
-
if @repository.save
-
flash[:notice] = t('flash.repository.saved')
-
redirect_to platform_repository_path(@platform, @repository)
-
else
-
flash[:error] = t('flash.repository.save_error')
-
render action: :new
-
end
-
end
-
-
1
def add_project
-
authorize @repository
-
if projects_list = params.try(:[], :repository).try(:[], :projects_list)
-
@repository.add_projects projects_list, current_user
-
redirect_to platform_repository_path(@platform, @repository), notice: t('flash.repository.projects_will_be_added')
-
return
-
end
-
if params[:project_id].present?
-
@project = Project.find(params[:project_id])
-
if policy(@project).read?
-
begin
-
@repository.projects << @project
-
flash[:notice] = t('flash.repository.project_added')
-
rescue ActiveRecord::RecordInvalid
-
flash[:error] = t('flash.repository.project_not_added')
-
end
-
else
-
flash[:error] = t('flash.repository.no_access_to_read_project')
-
end
-
redirect_to platform_repository_path(@platform, @repository)
-
else
-
render :projects_list
-
end
-
end
-
-
1
def projects_list
-
render(text: @repository.projects.map(&:name).join("\n")) && return if params[:text] == 'true'
-
-
owner_subquery = "
-
INNER JOIN (
-
SELECT id, 'User' AS type, uname
-
FROM users
-
UNION
-
SELECT id, 'Group' AS type, uname
-
FROM groups
-
) AS owner
-
ON projects.owner_id = owner.id AND projects.owner_type = owner.type"
-
-
if params[:added] == "true"
-
@projects = @repository.projects
-
else
-
@projects = Project.joins(owner_subquery).addable_to_repository(@repository.id)
-
@projects = @projects.opened if @repository.platform.main? && !@repository.platform.hidden?
-
end
-
# @projects = @projects.paginate(page: page, per_page: per_page)
-
-
# @total_projects = @projects.count
-
@projects = @projects.by_owner(params[:owner_name]).
-
search_like(params[:project_name]).order("projects.name #{sort_dir}")
-
-
@total_items = @projects.count
-
@projects = @projects.paginate(paginate_params)
-
-
respond_to do |format|
-
format.json {
-
render partial: (params[:added] == "true") ? 'project' : 'proj_ajax', layout: false
-
}
-
end
-
end
-
-
1
def remove_project
-
if projects_list = params.try(:[], :repository).try(:[], :projects_list)
-
@repository.remove_projects projects_list
-
redirect_to platform_repository_path(@platform, @repository), notice: t('flash.repository.projects_will_be_removed')
-
end
-
if params[:project_id].present?
-
ProjectToRepository.where(project_id: params[:project_id], repository_id: @repository.id).destroy_all
-
message = t('flash.repository.project_removed')
-
respond_to do |format|
-
format.html {redirect_to platform_repository_path(@platform, @repository), notice: message}
-
format.json {render json: { message: message }}
-
end
-
end
-
end
-
-
1
def regenerate_metadata
-
authorize @repository
-
resign_rpms = params[:repository][:resign_rpms] == '1'
-
if @repository.regenerate(params[:repository].try(:[], :build_for_platform_id), resign_rpms)
-
flash[:notice] = t('flash.repository.regenerate_in_queue')
-
else
-
flash[:error] = t('flash.repository.regenerate_already_in_queue')
-
end
-
redirect_to platform_repository_path(@platform, @repository)
-
end
-
-
1
def sync_lock_file
-
if params[:remove]
-
@repository.remove_sync_lock_file
-
flash[:notice] = t('flash.repository.sync_lock_file_removed')
-
else
-
flash[:notice] = t('flash.repository.sync_lock_file_added')
-
@repository.add_sync_lock_file
-
end
-
redirect_to edit_platform_repository_path(@platform, @repository)
-
end
-
-
1
protected
-
-
1
def repository_params
-
subject_params(Repository)
-
end
-
-
# Private: before_action hook which loads Repository.
-
1
def load_repository
-
authorize @repository = @platform.repositories.find(params[:id])
-
end
-
-
1
def set_members
-
@members = @repository.members.order('name')
-
end
-
-
end
-
1
class Platforms::TokensController < Platforms::BaseController
-
1
before_action :authenticate_user!
-
-
1
before_action :load_token, except: [:index, :create, :new]
-
-
1
def index
-
authorize @platform, :local_admin_manage?
-
@tokens = @platform.tokens.includes(:creator, :updater)
-
.paginate(per_page: 20, page: params[:page])
-
end
-
-
1
def show
-
end
-
-
1
def withdraw
-
if @token.block
-
@token.updater = current_user
-
@token.save
-
flash[:notice] = t('flash.tokens.withdraw_success')
-
redirect_back(fallback_location: {
-
id: @token.id,
-
platform_id: subject_id
-
})
-
else
-
flash[:notice] = t('flash.tokens.withdraw_fail')
-
redirect_back(fallback_location: {
-
id: @token.id,
-
platform_id: subject_id
-
})
-
end
-
end
-
-
1
def new
-
authorize @token = @platform.tokens.new
-
end
-
-
1
def create
-
@token = @platform.tokens.build token_params
-
@token.creator = current_user
-
authorize @token
-
if @token.save
-
flash[:notice] = t('flash.tokens.saved')
-
redirect_to platform_tokens_path(@platform)
-
else
-
flash[:error] = t('flash.tokens.save_error')
-
flash[:warning] = @token.errors.map(&:full_message).join('. ') unless @token.errors.empty?
-
render :new
-
end
-
end
-
-
1
protected
-
-
1
def token_params
-
subject_params(Token)
-
end
-
-
# Private: before_action hook which loads Repository.
-
1
def load_token
-
authorize @token = @platform.tokens.find(params[:id])
-
end
-
-
end
-
1
class Projects::BaseController < ApplicationController
-
1
prepend_before_action :authenticate_user_and_find_project
-
1
before_action :init_statistics
-
-
1
protected
-
-
1
def find_collaborators
-
search = "%#{params[:search_user]}%"
-
@users = @project.collaborators.where("users.uname ILIKE ?", search)
-
@users |= @project.owner.members.where("users.uname ILIKE ?", search) if @project.owner.is_a?(Group)
-
@users = @users.sort_by(&:uname).first(10)
-
end
-
-
1
def authenticate_user_and_find_project
-
3
authenticate_user
-
3
return if params[:name_with_owner].blank?
-
1
authorize @project = Project.find_by_owner_and_name!(params[:name_with_owner]), :show?
-
end
-
-
1
def init_statistics
-
3
if @project
-
1
@opened_issues_count = @project.issues.without_pull_requests.not_closed_or_merged.count
-
1
@opened_pull_requests_count = @project.issues.joins(:pull_request).not_closed_or_merged.count
-
end
-
end
-
end
-
1
class Projects::BuildListsController < Projects::BaseController
-
1
include FileStoreHelper
-
1
include BuildListsHelper
-
-
1
NESTED_ACTIONS = [:index, :new, :create, :list]
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:show, :index, :log] if APP_CONFIG['anonymous_access']
-
-
1
before_action :load_build_list, except: NESTED_ACTIONS
-
-
1
before_action :create_from_build_list, only: :new
-
-
1
def index
-
authorize :build_list
-
params[:filter].each{|k,v| params[:filter].delete(k) if v.blank? } if params[:filter]
-
-
respond_to do |format|
-
format.html
-
format.json do
-
@filter = BuildList::Filter.new(@project, current_user, params[:filter] || {})
-
params[:page] = params[:page].to_i == 0 ? nil : params[:page]
-
params[:per_page] = if BuildList::Filter::PER_PAGE.include? params[:per_page].to_i
-
params[:per_page].to_i
-
else
-
BuildList::Filter::PER_PAGE.first
-
end
-
@bls_count = @filter.find.count
-
@bls = @filter.find.recent.paginate(page: params[:page], per_page: params[:per_page])
-
@build_lists = BuildList.where(id: @bls.pluck(:id)).recent
-
.includes(:save_to_platform,
-
:save_to_repository,
-
:build_for_platform,
-
:user,
-
:source_packages,
-
project: :project_statistics)
-
-
@build_server_status = AbfWorkerStatusPresenter.new.projects_status
-
end
-
end
-
end
-
-
1
def new
-
1
authorize @build_list = @project.build_lists.build
-
1
if params[:show] == 'inline' && params[:build_list_id].present?
-
render json: new_build_list_data(@build_list, @project, params), layout: false
-
else
-
1
render :new
-
end
-
end
-
-
1
def create
-
notices, errors = [], []
-
-
@repository = Repository.find build_list_params[:save_to_repository_id]
-
@platform = @repository.platform
-
-
build_lists = []
-
build_for_platforms = Platform.joins(:repositories).where(repositories: { id: build_list_params[:include_repos] }).distinct
-
Arch.where(id: params[:arches]).each do |arch|
-
build_for_platforms.find_each do |build_for_platform|
-
@build_list = @project.build_lists.build(build_list_params)
-
@build_list.save_to_platform = @platform
-
@build_list.build_for_platform = build_for_platform
-
@build_list.arch = arch
-
@build_list.user = current_user
-
@build_list.include_repos = @build_list.include_repos.select {|ir| @build_list.build_for_platform.repository_ids.include? ir.to_i}
-
@build_list.priority = current_user.build_priority # User builds more priority than mass rebuild with zero priority
-
-
flash_options = { project_version: @build_list.project_version, arch: arch.name, build_for_platform: build_for_platform.name }
-
authorize @build_list
-
if @build_list.save
-
build_lists << @build_list
-
notices << t('flash.build_list.saved', flash_options)
-
else
-
errors << t('flash.build_list.save_error', flash_options)
-
end
-
end
-
end
-
errors << t('flash.build_list.no_arch_or_platform_selected') if errors.blank? and notices.blank?
-
if errors.present?
-
@build_list ||= BuildList.new
-
flash[:error] = errors.join('<br>').html_safe
-
render action: :new
-
else
-
BuildList.where(id: build_lists.map(&:id)).update_all(group_id: build_lists[0].id) if build_lists.size > 1
-
flash[:notice] = notices.join('<br>').html_safe
-
redirect_to project_build_lists_path(@project)
-
end
-
end
-
-
1
def show
-
@item_groups = @build_list.items.group_by_level
-
end
-
-
1
def publish
-
@build_list.update_type = params[:build_list][:update_type] if params[:build_list][:update_type].present?
-
-
if params[:attach_advisory].present? and params[:attach_advisory] != 'no' and !@build_list.advisory
-
-
unless @build_list.update_type.in? BuildList::RELEASE_UPDATE_TYPES
-
flash[:notice] = t('layout.build_lists.publish_fail')
-
redirect_back(fallback_location: build_list_path(@build_list.id))
-
return
-
end
-
-
if params[:attach_advisory] == 'new'
-
# create new advisory
-
unless @build_list.associate_and_create_advisory(advisory_params)
-
flash[:notice] = t('layout.build_lists.publish_fail')
-
redirect_back(fallback_location: build_list_path(@build_list.id))
-
return
-
end
-
else
-
# attach existing advisory
-
a = Advisory.find_by(advisory_id: params[:attach_advisory])
-
unless (a && a.attach_build_list(@build_list))
-
flash[:notice] = t('layout.build_lists.publish_fail')
-
redirect_back(fallback_location: build_list_path(@build_list.id))
-
return
-
end
-
end
-
end
-
-
@build_list.publisher = current_user
-
do_and_back(:publish, 'publish_')
-
end
-
-
1
def dependent_projects
-
if request.post?
-
prs = params[:build_list]
-
if prs.present? && prs[:projects].present? && prs[:arches].present?
-
project_ids = prs[:projects].select{ |k, v| v == '1' }.keys
-
arch_ids = prs[:arches]. select{ |k, v| v == '1' }.keys
-
-
Resque.enqueue(
-
BuildLists::DependentPackagesJob,
-
@build_list.id,
-
current_user.id,
-
project_ids,
-
arch_ids,
-
{
-
auto_publish_status: prs[:auto_publish_status],
-
auto_create_container: prs[:auto_create_container],
-
include_testing_subrepository: prs[:include_testing_subrepository],
-
use_cached_chroot: prs[:use_cached_chroot],
-
use_extra_tests: prs[:use_extra_tests]
-
}
-
)
-
flash[:notice] = t('flash.build_list.dependent_projects_job_added_to_queue')
-
redirect_to build_list_path(@build_list)
-
end
-
end
-
end
-
-
1
def publish_into_testing
-
@build_list.publisher = current_user
-
do_and_back(:publish_into_testing, 'publish_')
-
end
-
-
1
def rerun_tests
-
2
do_and_back(:rerun_tests, 'rerun_tests_')
-
end
-
-
1
def reject_publish
-
@build_list.publisher = current_user
-
do_and_back(:reject_publish, 'reject_publish_')
-
end
-
-
1
def create_container
-
do_and_back(:publish_container, 'create_container_')
-
end
-
-
1
def cancel
-
do_and_back(:cancel, nil, 'will_be_canceled', 'cancel_fail')
-
end
-
-
1
def log
-
render json: {
-
log: @build_list.log,
-
building: @build_list.build_started?
-
}
-
end
-
-
1
def list
-
@build_lists = @project.build_lists
-
@build_lists = @build_lists.where(user_id: current_user) if params[:owner_filter] == 'true'
-
@build_lists = @build_lists.where(status: [BuildList::BUILD_ERROR, BuildList::FAILED_PUBLISH, BuildList::REJECTED_PUBLISH]) if params[:status_filter] == 'true'
-
-
@total_build_lists = @build_lists.count
-
-
@build_lists = @build_lists.recent.paginate(page: current_page)
-
-
render partial: 'build_lists_ajax', layout: false
-
end
-
-
1
def update_type
-
respond_to do |format|
-
format.html { head :ok }
-
format.json do
-
@build_list.update_type = params[:update_type]
-
if @build_list.save
-
render json: 'success', status: :ok
-
else
-
render json: { message: @build_list.errors.map(&:full_message).join('. ') },
-
status: :unprocessable_entity
-
end
-
end
-
end
-
end
-
-
1
protected
-
-
1
def build_list_params
-
subject_params(BuildList)
-
end
-
-
1
def advisory_params
-
permit_params(%i(build_list advisory), *policy(Advisory).permitted_attributes)
-
end
-
-
# Private: before_action hook which loads BuidList.
-
1
def load_build_list
-
2
authorize @build_list =
-
2
if @project
-
@project.build_lists
-
else
-
2
BuildList
-
end.find(params[:id])
-
end
-
-
1
def do_and_back(action, prefix, success = 'success', fail = 'fail')
-
2
result = @build_list.send("can_#{action}?") && @build_list.send(action)
-
2
message = result ? success : fail
-
2
flash[result ? :notice : :error] = t("layout.build_lists.#{prefix}#{message}")
-
2
redirect_back(fallback_location: build_list_path(@build_list.id))
-
end
-
-
1
def create_from_build_list
-
1
return if params[:build_list_id].blank?
-
build_list = @project.build_lists.find(params[:build_list_id])
-
params[:build_list] = build_list.attributes
-
params[:arches] = [build_list.arch_id]
-
[:owner_filter, :status_filter].each { |t| params[t] = 'true' if %w(true undefined).exclude? params[t] }
-
end
-
end
-
1
class Projects::CollaboratorsController < Projects::BaseController
-
1
before_action :authenticate_user!
-
1
before_action :authorize_collaborators
-
-
1
before_action :find_users
-
1
before_action :find_groups
-
-
1
def index
-
@collaborators = Collaborator.find_by_project(@project)
-
end
-
-
1
def find
-
users = User.not_member_of(@project)
-
groups = Group.not_member_of(@project)
-
if params[:term].present?
-
users = users.search_like(params[:term]).first(5)
-
groups = groups.search_like(params[:term]).first(5)
-
end
-
@collaborators = (users | groups).map{|act| Collaborator.new(actor: act, project: @project)}
-
end
-
-
1
def create
-
@collaborator = Collaborator.new(collaborator_params)
-
@collaborator.project = @project
-
respond_to do |format|
-
if @collaborator.save
-
format.json { render partial: 'collaborator', locals: {collaborator: @collaborator, success: true} }
-
else
-
format.json { render json: {message:t('flash.collaborators.error_in_adding')}, status: 422 }
-
end
-
end
-
end
-
-
1
def update
-
cb = Collaborator.find(params[:id])
-
respond_to do |format|
-
if cb.update(params[:collaborator])
-
format.json { render json: {message:t('flash.collaborators.successfully_updated', uname: cb.actor.uname)} }
-
else
-
format.json { render json: {message:t('flash.collaborators.error_in_updating')}, status: 422 }
-
end
-
end
-
end
-
-
1
def destroy
-
cb = Collaborator.find(params[:id])
-
respond_to do |format|
-
if cb.present? && cb.destroy
-
format.json { render json: {message:t('flash.collaborators.successfully_removed', uname: cb.actor.uname)} }
-
else
-
format.json {
-
render json: {message:t('flash.collaborators.error_in_removing', uname: cb.try(:actor).try(:uname))},
-
status: 422
-
}
-
end
-
end
-
end
-
-
1
protected
-
-
1
def collaborator_params
-
subject_params(Collaborator)
-
end
-
-
1
def find_users
-
@users = @project.collaborators.order('uname')#User.all
-
@users = @users.without_ids(@project.owner_id) if @project.owner_type == 'User'
-
end
-
-
1
def find_groups
-
@groups = @project.groups.order('uname')#Group.all
-
@groups = @groups.without_ids(@project.owner_id) if @project.owner_type == 'Group'
-
end
-
-
1
def authorize_collaborators
-
authorize @project, :update?
-
end
-
end
-
1
class Projects::CommentsController < Projects::BaseController
-
1
before_action :authenticate_user!
-
1
before_action :find_commentable
-
1
before_action :find_or_build_comment
-
-
1
include CommentsHelper
-
-
1
def create
-
respond_to do |format|
-
if !@comment.set_additional_data params
-
format.json {
-
render json: {
-
message: I18n.t("flash.comment.save_error"),
-
error: @comment.errors.map(&:full_message)
-
}
-
}
-
elsif @comment.save
-
format.json {}
-
else
-
format.json { render json: { message: I18n.t("flash.comment.save_error") }, status: 422 }
-
end
-
end
-
end
-
-
1
def edit
-
end
-
-
1
def update
-
respond_to do |format|
-
if @comment.update(comment_params)
-
format.json { render json: {message:t('flash.comment.updated'), body: view_context.markdown(@comment.body)} }
-
else
-
format.json { render json: {message:t('flash.comment.error_in_updating')}, status: 422 }
-
end
-
end
-
end
-
-
1
def destroy
-
respond_to do |format|
-
if @comment.present? && @comment.destroy
-
format.json { render json: {message: I18n.t('flash.comment.destroyed')} }
-
else
-
format.json {
-
render json: {message: t('flash.comment.error_in_deleting')}, status: 422 }
-
end
-
end
-
end
-
-
1
protected
-
-
1
def comment_params
-
subject_params(Comment)
-
end
-
-
1
def find_commentable
-
@commentable = params[:issue_id].present? && @project.issues.find_by(serial_id: params[:issue_id]) ||
-
params[:commit_id].present? && @project.repo.commit(params[:commit_id])
-
end
-
-
1
def find_or_build_comment
-
@comment = params[:id].present? && Comment.where(automatic: false).find(params[:id]) ||
-
current_user.comments.build(comment_params) {|c| c.commentable = @commentable; c.project = @project}
-
authorize @comment
-
end
-
end
-
1
class Projects::CommitSubscribesController < Projects::BaseController
-
1
before_action :authenticate_user!
-
1
before_action :find_commit
-
-
1
def create
-
if Subscribe.subscribe_to_commit(@options)
-
flash[:notice] = I18n.t("flash.subscribe.commit.saved")
-
# TODO js
-
redirect_to commit_path(@project, @commit)
-
else
-
flash[:error] = I18n.t("flash.subscribe.saved_error")
-
redirect_to commit_path(@project, @commit)
-
end
-
end
-
-
1
def destroy
-
Subscribe.unsubscribe_from_commit(@options)
-
flash[:notice] = t("flash.subscribe.commit.destroyed")
-
redirect_to commit_path(@project, @commit)
-
end
-
-
1
protected
-
-
1
def find_commit
-
@commit = @project.repo.commit(params[:commit_id])
-
@options = {project_id: @project.id, subscribeable_id: @commit.id.hex, subscribeable_type: @commit.class.name, user_id: current_user.id}
-
end
-
end
-
1
class Projects::Git::BaseController < Projects::BaseController
-
1
before_action :authenticate_user!
-
1
if APP_CONFIG['anonymous_access']
-
1
skip_before_action :authenticate_user!, only: %i(show index blame raw archive get_sha1_of_archive diff tags branches)
-
1
before_action :authenticate_user, only: %i(show index blame raw archive get_sha1_of_archive diff tags branches)
-
end
-
-
1
before_action :set_treeish_and_path
-
1
before_action :set_branch_and_tree
-
-
1
protected
-
-
1
def set_treeish_and_path
-
@treeish, @path = params[:treeish].presence || @project.default_head, params[:path]
-
end
-
-
1
def set_branch_and_tree
-
@branch = @project.repo.branches.detect{|b| b.name == @treeish}
-
@tree = @project.repo.tree(@treeish)
-
# raise Grit::NoSuchPathError if @tree.blobs.blank?
-
end
-
end
-
1
class Projects::Git::BlobsController < Projects::Git::BaseController
-
1
before_action :set_blob
-
1
before_action -> {authorize @project, :write? }, only: [:edit, :update]
-
-
1
def show
-
end
-
-
1
def edit
-
rugged = @blob.repo.rugged
-
@lazy = Linguist::LazyBlob.new(rugged, @blob.id, @path, @blob.mode)
-
end
-
-
1
def update
-
if @project.update_file(params[:path], params[:content].gsub("\r", ''),
-
message: params[:message].gsub("\r", ''), actor: current_user, head: @treeish)
-
flash[:notice] = t("flash.blob.successfully_updated", name: params[:path])
-
else
-
flash[:notice] = t("flash.blob.updating_error", name: params[:path])
-
end
-
redirect_to action: :show
-
end
-
-
1
def blame
-
@blame = Grit::Blob.blame(@project.repo, @commit.id, @path)
-
end
-
-
1
def raw
-
repo = Grit::GitRuby::Repository.new(@project.repo.path)
-
raw = repo.get_raw_object_by_sha1(@blob.id)
-
send_data raw.content, type: @blob.content_type, disposition: @blob.disposition
-
end
-
-
1
protected
-
-
1
def set_blob
-
@blob = @tree / @path or raise Grit::NoSuchPathError
-
redirect_to tree_path(@project, treeish: @treeish, path: @path) if @blob.is_a? Grit::Tree
-
@commit = @project.repo.log(@treeish, @path, max_count: 1).first
-
end
-
end
-
1
class Projects::Git::CommitsController < Projects::Git::BaseController
-
-
1
def index
-
if @path.present?
-
@commits = @project.repo.log(@treeish, @path)
-
else
-
@commits, @page, @last_page = @project.paginate_commits(@treeish, page: params[:page])
-
end
-
end
-
-
1
def show
-
@commit = @commentable = @project.repo.commit(params[:id]) || raise(ActiveRecord::RecordNotFound)
-
@comments = Comment.for_commit(@commit)
-
-
respond_to do |format|
-
format.html
-
format.diff { render plain: (@commit.show.map(&:diff).join("\n") rescue ''), content_type: "text/plain" }
-
format.patch { render plain: (@commit.to_patch rescue ''), content_type: "text/plain" }
-
end
-
end
-
-
1
def diff
-
res = params[:diff].split(/\A(.*)\.\.\.(.*)\z/).select {|e| e.present?}
-
if res[1].present?
-
params1 = res[0]
-
params2 = res[1] == 'HEAD' ? @project.resolve_default_branch : res.last
-
else # get only one parameter
-
params1 = @project.resolve_default_branch
-
params2 = res.first
-
end
-
params1.sub! 'HEAD', @project.resolve_default_branch
-
params2.sub! 'HEAD', @project.resolve_default_branch
-
-
ref1 = if @project.repo.branches_and_tags.include? params1
-
@project.repo.commits(params1).first
-
else
-
params1 # possible commit hash
-
end
-
@commit1 = @project.repo.commit(ref1) || raise(ActiveRecord::RecordNotFound)
-
-
ref = if @project.repo.branches_and_tags.include? params2
-
@project.repo.commits(params2).first
-
else
-
params2 # possible commit hash
-
end
-
@commit = @project.repo.commit(ref) || raise(ActiveRecord::RecordNotFound)
-
@common_ancestor = @project.repo.commit(@project.repo.git.merge_base({}, @commit1, @commit)) || @commit1
-
@stats = @project.repo.diff_stats @commit1.id, @commit.id
-
end
-
end
-
1
class Projects::Git::TreesController < Projects::Git::BaseController
-
-
1
skip_before_action :set_branch_and_tree, only: [:archive, :get_sha1_of_archive]
-
1
skip_before_action :set_treeish_and_path, only: [:archive, :get_sha1_of_archive]
-
1
before_action :redirect_to_project, only: :show
-
1
before_action :resolve_treeish, only: [:branch, :destroy]
-
-
# skip_authorize_resource :project, only: [:destroy, :restore_branch, :create]
-
1
before_action -> { authorize(@project, :show?) }, only: [:show, :archive, :tags, :branches, :get_sha1_of_archive]
-
-
1
def show
-
unless request.xhr?
-
render('empty') and return if @project.is_empty?
-
@tree = @tree / @path if @path.present?
-
@commit = @branch.present? ? @branch.commit() : @project.repo.log(@treeish, @path, max_count: 1).first
-
raise Grit::NoSuchPathError unless @commit
-
else
-
@tree = @tree / @path if @path.present?
-
end
-
end
-
-
1
def archive
-
format, @treeish = params[:format], params[:treeish]
-
raise Grit::NoSuchPathError unless @treeish =~ /^#{@project.name}-/ &&
-
@treeish !~ /[\s]+/ &&
-
format =~ /\A(zip|tar\.gz)\z/
-
@treeish.gsub!(/^#{@project.name}-/, '')
-
@commit = @project.repo.commits(@treeish, 1).first
-
raise Grit::NoSuchPathError unless @commit
-
tag = @project.repo.tags.find{ |t| t.name == @treeish }
-
sha1 = @project.get_project_tag_sha1(tag, format) if tag
-
-
if sha1.present?
-
redirect_to "#{APP_CONFIG['file_store_url']}/api/v1/file_stores/#{sha1}"
-
else
-
archive = @project.archive_by_treeish_and_format @treeish, format
-
send_file archive[:path], disposition: 'attachment', type: "application/#{format == 'zip' ? 'zip' : 'x-tar-gz'}", filename: archive[:fullname]
-
end
-
end
-
-
1
def get_sha1_of_archive
-
format, @treeish = params[:format], params[:treeish]
-
raise Grit::NoSuchPathError unless @treeish =~ /^#{@project.name}-/ &&
-
@treeish !~ /[\s]+/ &&
-
format =~ /\A(zip|tar\.gz)\z/
-
@treeish.gsub!(/^#{@project.name}-/, '')
-
@commit = @project.repo.commits(@treeish, 1).first
-
raise Grit::NoSuchPathError unless @commit
-
tag = @project.repo.tags.find{ |t| t.name == @treeish }
-
sha1 = @project.get_project_tag_sha1(tag, format) if tag
-
sha1 ||= ''
-
-
render plain: sha1
-
end
-
-
1
def tags
-
if request.xhr?
-
@refs = @project.repo.tags.select{ |t| t.commit }.sort_by(&:name).reverse
-
render :refs_list
-
else
-
respond_to do |format|
-
format.json { head 422 }
-
format.html
-
end
-
end
-
end
-
-
1
def restore_branch
-
authorize @project, :write?
-
status = @project.create_branch(@treeish, params[:sha], current_user) ? 200 : 422
-
head status
-
end
-
-
1
def create
-
authorize @project, :write?
-
status = @project.create_branch(params[:new_ref], params[:from_ref], current_user) ? 200 : 422
-
head status
-
end
-
-
1
def destroy
-
authorize @project, :write?
-
status = @branch && @project.delete_branch(@branch, current_user) ? 200 : 422
-
head status
-
end
-
-
1
def branches
-
if request.xhr?
-
@refs = @project.repo.branches.sort_by(&:name)
-
render :refs_list
-
else
-
respond_to do |format|
-
format.json { head 422 }
-
format.html
-
end
-
end
-
end
-
-
1
protected
-
-
1
def resolve_treeish
-
raise Grit::NoSuchPathError if params[:treeish] != @branch.try(:name)
-
end
-
-
1
def redirect_to_project
-
if params[:treeish] == @project.resolve_default_branch && params[:path].blank? && !request.xhr?
-
redirect_to @project
-
end
-
end
-
-
end
-
1
class Projects::HooksController < Projects::BaseController
-
1
before_action :authenticate_user!
-
1
before_action -> { authorize @project, :update? }
-
1
before_action :load_hook, except: %i(index new create)
-
-
1
def index
-
@name = params[:name]
-
@hooks = @project.hooks.for_name(@name).order('name asc, created_at desc')
-
render(:show) if @name.present?
-
end
-
-
1
def new
-
@hook = @project.hooks.build
-
end
-
-
1
def edit
-
end
-
-
1
def create
-
authorize @hook = @project.hooks.build(hook_params)
-
if @hook.save
-
redirect_to project_hooks_path(@project, name: @hook.name), notice: t('flash.hook.created')
-
else
-
flash[:error] = t('flash.hook.save_error')
-
flash[:warning] = @hook.errors.map(&:full_message).join('. ')
-
render :new
-
end
-
end
-
-
1
def update
-
if @hook.update(hook_params)
-
redirect_to project_hooks_path(@project, name: @hook.name), notice: t('flash.hook.updated')
-
else
-
flash[:error] = t('flash.hook.save_error')
-
flash[:warning] = @hook.errors.map(&:full_message).join('. ')
-
render :edit
-
end
-
end
-
-
1
def destroy
-
@hook.destroy
-
redirect_to project_hooks_path(@project, name: @hook.name)
-
end
-
-
1
private
-
-
1
def hook_params
-
subject_params(Hook)
-
end
-
-
# Private: before_action hook which loads Hook.
-
1
def load_hook
-
authorize @hook = @project.hooks.find(params[:id])
-
end
-
-
end
-
1
class Projects::IssuesController < Projects::BaseController
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:index, :show, :pull_requests] if APP_CONFIG['anonymous_access']
-
1
before_action :load_issue, only: %i(show edit update destroy)
-
1
before_action :load_and_authorize_label, only: %i(create_label update_label destroy_label)
-
1
before_action :find_collaborators, only: :search_collaborators
-
-
1
layout false, only: [:update, :search_collaborators]
-
-
1
def index
-
params[:kind] = params[:kind] == 'pull_requests' ? 'pull_requests' : 'issues'
-
raise Pundit::NotAuthorizedError if !@project.has_issues? && params[:kind] == 'issues'
-
-
params[:filter] = params[:filter].in?(['created', 'assigned']) ? params[:filter] : 'all'
-
params[:sort] = params[:sort] == 'submitted' ? 'submitted' : 'updated'
-
params[:direction] = params[:direction] == 'asc' ? :asc : :desc
-
params[:status] = params[:status] == 'closed' ? :closed : :open
-
if !params[:labels].is_a?(Array) || params[:labels].blank?
-
params[:labels] = []
-
end
-
-
respond_to do |format|
-
format.html { render 'index' }
-
format.json do
-
all_issues =
-
if params[:kind] == 'pull_requests'
-
@project.issues.joins(:pull_request)
-
else
-
@project.issues.without_pull_requests
-
end
-
-
@all_issues = all_issues
-
if current_user
-
@created_issues = all_issues.where(user_id: current_user)
-
@assigned_issues = all_issues.where(assignee_id: current_user)
-
end
-
-
case params[:filter]
-
when 'created'
-
@issues = @created_issues
-
when 'assigned'
-
@issues = @assigned_issues
-
else
-
@issues = all_issues
-
end
-
-
if params[:labels].is_a?(Array) && params[:labels].present?
-
@issues = @issues.joins(:labels).where(labels: {name: params[:labels]})
-
end
-
-
@opened_issues, @closed_issues = @issues.not_closed_or_merged, @issues.closed_or_merged
-
@issues = @issues.send( params[:status] == :closed ? :closed_or_merged : :not_closed_or_merged )
-
-
if params[:sort] == 'submitted'
-
@issues = @issues.order(created_at: params[:direction])
-
else
-
@issues = @issues.order(updated_at: params[:direction])
-
end
-
-
@issues = @issues.includes(:assignee, :user, :pull_request).uniq
-
.paginate(page: current_page)
-
-
render 'index'
-
end
-
end
-
end
-
-
1
def pull_requests
-
params[:kind] = 'pull_requests'
-
index
-
end
-
-
1
def labels
-
render partial: 'projects/issues/labels.json', locals: {project: @project}, layout: false
-
end
-
-
1
def new
-
authorize @issue = @project.issues.build
-
end
-
-
1
def create
-
@issue = @project.issues.new
-
@issue.assign_attributes(issue_params)
-
@issue.user = current_user
-
-
authorize @issue
-
if @issue.save
-
@issue.subscribe_creator(current_user.id)
-
flash[:notice] = I18n.t("flash.issue.saved")
-
redirect_to project_issues_path(@project)
-
else
-
flash[:error] = I18n.t("flash.issue.save_error")
-
render action: :new
-
end
-
end
-
-
1
def show
-
redirect_to project_pull_request_path(@project, @issue.pull_request) if @issue.pull_request
-
@commentable = @issue
-
end
-
-
1
def update
-
respond_to do |format|
-
format.html { head :ok }
-
-
format.json {
-
status = 200
-
if params[:issue] && status = params[:issue][:status]
-
@issue.set_close(current_user) if status == 'closed'
-
@issue.set_open if status == 'open'
-
status = @issue.save ? 200 : 500
-
else
-
status = 422 unless @issue.update(issue_params)
-
end
-
render status: status
-
}
-
end
-
end
-
-
# def destroy
-
# @issue.destroy
-
# flash[:notice] = t("flash.issue.destroyed")
-
# redirect_to root_path
-
# end
-
-
1
def create_label
-
@label = @project.labels.new(name: params[:name], color: params[:color])
-
respond_to do |format|
-
if @label.save
-
format.json { render partial: 'labels', locals: {project: @project} }
-
else
-
format.json { render plain: @label.errors.map(&:full_message), status: 422 }
-
end
-
end
-
end
-
-
1
def update_label
-
respond_to do |format|
-
if @label.update(name: params[:name], color: params[:color])
-
format.json { render partial: 'labels', locals: {project: @project} }
-
else
-
format.json { render plain: @label.errors.map(&:full_message), status: 422 }
-
end
-
end
-
end
-
-
1
def destroy_label
-
respond_to do |format|
-
if @label.destroy
-
format.json { render partial: 'labels', locals: {project: @project} }
-
else
-
format.json { render json: @label.errors.map(&:full_message), status: 422 }
-
end
-
end
-
end
-
-
1
def search_collaborators
-
end
-
-
1
private
-
-
1
def issue_params
-
subject_params(Issue, @issue)
-
end
-
-
# Private: before_action hook which loads Issue.
-
1
def load_issue
-
authorize @issue = @project.issues.find_by!(serial_id: params[:id])
-
end
-
-
# Private: before_action hook which loads Label.
-
1
def load_and_authorize_label
-
authorize @project, :write?
-
@label = @project.labels.find(params[:label_id]) if params[:label_id]
-
end
-
end
-
1
class Projects::ProjectsController < Projects::BaseController
-
1
include DatatableHelper
-
1
include ProjectsHelper
-
-
1
before_action :authenticate_user!
-
1
before_action :who_owns, only: [:new, :create, :mass_import, :run_mass_import]
-
-
1
def index
-
authorize :project
-
@projects = ProjectPolicy::Scope.new(current_user, Project).membered.search_like(params[:search])
-
respond_to do |format|
-
format.html {
-
@groups = current_user.groups
-
@owners = User.where(id: @projects.where(owner_type: 'User').uniq.pluck(:owner_id))
-
}
-
format.json {
-
groups = params[:groups] || []
-
owners = params[:users] || []
-
@projects = @projects.by_owners(groups, owners) if groups.present? || owners.present?
-
@projects_count = @projects.count
-
@projects = @projects.recent.paginate(page: current_page, per_page: Project.per_page)
-
}
-
end
-
end
-
-
1
def new
-
authorize :project
-
@project = Project.new
-
end
-
-
1
def mass_import
-
authorize :project
-
@project = Project.new(mass_import: true)
-
end
-
-
1
def run_mass_import
-
@project = Project.new project_params
-
@project.owner = choose_owner
-
authorize @project
-
@project.valid?
-
@project.errors.messages.slice! :url
-
if @project.errors.messages.blank? # We need only url validation
-
@project.init_mass_import
-
flash[:notice] = t('flash.project.mass_import_added_to_queue')
-
redirect_to projects_path
-
else
-
render :mass_import
-
end
-
end
-
-
1
def edit
-
authorize @project
-
@project_aliases = Project.project_aliases(@project).paginate(page: current_page)
-
end
-
-
1
def create
-
@project = Project.new project_params
-
@project.owner = choose_owner
-
authorize @project
-
-
if @project.save
-
flash[:notice] = t('flash.project.saved')
-
redirect_to @project
-
else
-
flash[:error] = t('flash.project.save_error')
-
flash[:warning] = @project.errors.map(&:full_message).join('. ')
-
render action: :new
-
end
-
end
-
-
1
def update
-
authorize @project
-
params[:project].delete(:maintainer_id) if params[:project][:maintainer_id].blank?
-
respond_to do |format|
-
format.html do
-
if @project.update(project_params)
-
flash[:notice] = t('flash.project.saved')
-
redirect_to @project
-
else
-
flash[:error] = t('flash.project.save_error')
-
flash[:warning] = @project.errors.map(&:full_message).join('. ')
-
render action: :edit
-
end
-
end
-
format.json do
-
if @project.update(project_params)
-
render json: { notice: I18n.t('flash.project.saved') }
-
else
-
render json: { error: I18n.t('flash.project.save_error') }, status: 422
-
end
-
end
-
end
-
end
-
-
1
def schedule
-
authorize @project
-
p_to_r = @project.project_to_repositories.find_by(repository_id: params[:repository_id])
-
unless p_to_r.repository.publish_without_qa
-
authorize p_to_r.repository.platform, :local_admin_manage?
-
end
-
p_to_r.user_id = current_user.id
-
p_to_r.enabled = params[:enabled].present?
-
p_to_r.auto_publish = params[:auto_publish].present?
-
p_to_r.save
-
if p_to_r.save
-
render json: { notice: I18n.t('flash.project.saved') }.to_json
-
else
-
render json: { error: I18n.t('flash.project.save_error') }.to_json, status: 422
-
end
-
end
-
-
1
def destroy
-
authorize @project
-
@project.destroy
-
flash[:notice] = t("flash.project.destroyed")
-
redirect_to @project.owner
-
end
-
-
1
def fork(is_alias = false)
-
owner = (Group.find params[:group] if params[:group].present?) || current_user
-
authorize owner, :write?
-
if forked = @project.fork(owner, new_name: params[:fork_name], is_alias: is_alias) and forked.valid?
-
redirect_to forked, notice: t("flash.project.forked")
-
else
-
flash[:warning] = t("flash.project.fork_error")
-
flash[:error] = forked.errors.map(&:full_message).join("\n")
-
redirect_to @project
-
end
-
end
-
-
1
def alias
-
authorize @project
-
fork(true)
-
end
-
-
1
def possible_forks
-
authorize @project
-
render partial: 'projects/git/base/forks', layout: false,
-
locals: { owner: current_user, name: (params[:name].presence || @project.name) }
-
end
-
-
1
def sections
-
authorize @project, :update?
-
if request.patch?
-
if @project.update(project_params)
-
flash[:notice] = t('flash.project.saved')
-
redirect_to sections_project_path(@project)
-
else
-
@project.save
-
flash[:error] = t('flash.project.save_error')
-
end
-
end
-
end
-
-
1
def remove_user
-
authorize @project
-
@project.relations.by_actor(current_user).destroy_all
-
respond_to do |format|
-
format.html do
-
flash[:notice] = t("flash.project.user_removed")
-
redirect_to projects_path
-
end
-
format.json { head :ok }
-
end
-
end
-
-
1
def autocomplete_maintainers
-
authorize @project
-
term, limit = params[:query], params[:limit] || 10
-
items = User.member_of_project(@project)
-
.where("users.name ILIKE ? OR users.uname ILIKE ?", "%#{term}%", "%#{term}%")
-
.limit(limit).map { |u| {name: u.fullname, id: u.id} }
-
render json: items
-
end
-
-
1
def preview
-
authorize @project
-
respond_to do |format|
-
format.json {}
-
format.html {render inline: view_context.markdown(params[:text]), layout: false}
-
end
-
end
-
-
1
def refs_list
-
authorize @project
-
refs = @project.repo.branches_and_tags.map(&:name)
-
@selected = params[:selected] if refs.include?(params[:selected])
-
@selected ||= @project.resolve_default_branch
-
render layout: false
-
end
-
-
1
protected
-
-
1
def project_params
-
subject_params(Project)
-
end
-
-
1
def who_owns
-
t = @project.try(:owner_type)
-
@who_owns = if t.nil?
-
:me
-
else
-
t == 'User' ? :me : :group
-
end
-
end
-
-
1
def choose_owner
-
if params[:who_owns] == 'group'
-
Group.find(params[:owner_id])
-
else
-
current_user
-
end
-
end
-
end
-
1
class Projects::PullRequestsController < Projects::BaseController
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:index, :show] if APP_CONFIG['anonymous_access']
-
-
1
before_action :load_issue, except: %i(index autocomplete_to_project new create)
-
1
before_action :load_pull, except: %i(index autocomplete_to_project new create)
-
-
1
def new
-
to_project = find_destination_project(false)
-
authorize to_project, :show?
-
-
@pull = to_project.pull_requests.new
-
@issue = @pull.issue = to_project.issues.new
-
set_attrs
-
-
authorize @pull
-
if PullRequest.check_ref(@pull, 'to', @pull.to_ref) && PullRequest.check_ref(@pull, 'from', @pull.from_ref) || @pull.uniq_merge
-
flash.now[:warning] = @pull.errors.map(&:full_message).join('. ')
-
else
-
@pull.check(false) # don't make event transaction
-
if @pull.already?
-
@pull.destroy
-
flash.now[:warning] = I18n.t('projects.pull_requests.up_to_date', to_ref: @pull.to_ref, from_ref: @pull.from_ref)
-
else
-
load_diff_commits_data
-
end
-
end
-
end
-
-
1
def create
-
unless pull_params
-
redirect :back
-
end
-
to_project = find_destination_project
-
authorize to_project, :show?
-
-
@pull = to_project.pull_requests.build pull_params
-
@issue = @pull.issue
-
@pull.issue.assignee_id = (params[:issue] || {})[:assignee_id] if policy(to_project).write?
-
@pull.issue.user, @pull.issue.project, @pull.from_project = current_user, to_project, @project
-
@pull.from_project_owner_uname = @pull.from_project.owner.uname
-
@pull.from_project_name = @pull.from_project.name
-
@pull.issue.new_pull_request = true
-
-
authorize @pull
-
if @pull.valid? # FIXME more clean/clever logics
-
@pull.save # set pull id
-
@pull.reload
-
@pull.check(false) # don't make event transaction
-
if @pull.already?
-
@pull.destroy
-
flash.now[:error] = I18n.t('projects.pull_requests.up_to_date', to_ref: @pull.to_ref, from_ref: @pull.from_ref)
-
render :new
-
else
-
@pull.send(@pull.status == 'blocked' ? 'block' : @pull.status)
-
redirect_to project_pull_request_path(@pull.to_project, @pull)
-
end
-
else
-
flash.now[:error] = t('flash.pull_request.save_error')
-
flash.now[:warning] = @pull.errors.map(&:full_message).join('. ')
-
-
if @pull.errors.try(:messages) && @pull.errors.messages[:to_ref].nil? && @pull.errors.messages[:from_ref].nil?
-
@pull.check(false) # don't make event transaction
-
load_diff_commits_data
-
end
-
render :new
-
end
-
end
-
-
1
def merge
-
authorize @pull
-
status = @pull.merge!(current_user) ? 200 : 422
-
head status
-
end
-
-
1
def update
-
authorize @pull
-
status = 422
-
if (action = params[:pull_request_action]) && %w(close reopen).include?(params[:pull_request_action])
-
if @pull.send("can_#{action}?")
-
@pull.set_user_and_time current_user
-
@pull.send(action)
-
@pull.check if @pull.open?
-
status = 200
-
end
-
end
-
head status
-
end
-
-
1
def show
-
if @pull.nil?
-
redirect_to project_issue_path(@project, @issue)
-
return
-
end
-
-
load_diff_commits_data
-
-
if params[:get_activity] == 'true'
-
render partial: 'activity', layout: false
-
elsif params[:get_diff] == 'true'
-
render partial: 'diff_tab', layout: false
-
elsif params[:get_commits] == 'true'
-
render partial: 'commits_tab', layout: false
-
end
-
end
-
-
1
def autocomplete_to_project
-
items = []
-
term = params[:query].to_s.strip.downcase
-
[ Project.where(id: @project.pull_requests.last.try(:to_project_id)),
-
@project.ancestors,
-
ProjectPolicy::Scope.new(current_user, Project).membered
-
].each do |p|
-
items.concat p.by_owner_and_name(term)
-
end
-
items = items.uniq{|i| i.id}.select{|e| e.repo.branches.count > 0}
-
render json: json_for_autocomplete_base(items)
-
end
-
-
1
protected
-
-
# Private: before_action hook which loads Issue.
-
1
def load_issue
-
@issue = @project.issues.find_by!(serial_id: params[:id])
-
end
-
-
# Private: before_action hook which loads PullRequest.
-
1
def load_pull
-
@pull = @issue.pull_request
-
authorize @pull, :show? if @pull
-
end
-
-
1
def pull_params
-
@pull_params ||= subject_params(PullRequest).presence
-
end
-
-
1
def json_for_autocomplete_base items
-
items.collect do |project|
-
{id: project.id.to_s, name: project.name_with_owner}
-
end
-
end
-
-
1
def load_diff_commits_data
-
@commits = @pull.repo.commits_between(@pull.to_commit, @pull.from_commit)
-
@total_commits = @commits.count
-
@commits = @commits.last(100)
-
-
@stats = @pull.diff_stats
-
@comments, @commentable = @issue.comments, @issue
-
end
-
-
1
def find_destination_project bang=true
-
project = Project.find_by_owner_and_name params[:to_project]
-
raise ActiveRecord::RecordNotFound if bang && !project
-
project || @project.pull_requests.last.try(:to_project) || @project.root
-
end
-
-
1
def set_attrs
-
if pull_params && pull_params[:issue_attributes]
-
@pull.issue.title = pull_params[:issue_attributes][:title].presence
-
@pull.issue.body = pull_params[:issue_attributes][:body].presence
-
end
-
@pull.from_project = @project
-
@pull.to_ref = (pull_params[:to_ref].presence if pull_params) || @pull.to_project.default_head
-
@pull.from_ref = params[:treeish].presence || (pull_params[:from_ref].presence if pull_params) || @pull.from_project.default_head(params[:treeish])
-
@pull.from_project_owner_uname = @pull.from_project.owner.uname
-
@pull.from_project_name = @pull.from_project.name
-
end
-
end
-
1
class Projects::SubscribesController < Projects::BaseController
-
1
before_action :authenticate_user!
-
-
1
before_action :load_issue
-
-
1
def create
-
authorize @subscribe = @issue.subscribes.build(user_id: current_user.id)
-
if @subscribe.save
-
flash[:notice] = I18n.t("flash.subscribe.saved")
-
redirect_back(fallback_location: '/')
-
else
-
flash[:error] = I18n.t("flash.subscribe.saved_error")
-
redirect_back(fallback_location: '/')
-
end
-
end
-
-
1
def destroy
-
authorize @subscribe = @issue.subscribes.find_by(user_id: current_user.id)
-
@subscribe.destroy
-
-
flash[:notice] = t("flash.subscribe.destroyed")
-
redirect_back(fallback_location: '/')
-
end
-
-
1
private
-
-
# Private: before_action hook which loads Issue.
-
1
def load_issue
-
authorize @issue = @project.issues.find_by!(serial_id: params[:issue_id]), :show?
-
end
-
end
-
#require 'lib/gollum'
-
1
require 'cgi'
-
-
1
class Projects::WikiController < Projects::BaseController
-
1
WIKI_OPTIONS = {}
-
-
1
before_action :authenticate_user!
-
1
skip_before_action :authenticate_user!, only: [:show, :index, :git, :compare, :compare_wiki, :history, :wiki_history, :search, :pages] if APP_CONFIG['anonymous_access']
-
-
1
before_action :authorize_read_actions, only: [:index, :show, :git, :compare, :compare_wiki, :history, :wiki_history, :search, :pages]
-
1
before_action :authorize_write_actions, only: [:edit, :update, :new, :create, :destroy, :revert, :revert_wiki, :preview]
-
1
before_action :get_wiki
-
-
1
def index
-
@name = 'Home'
-
@page = @wiki.page(@name)
-
-
show_or_create_page
-
end
-
-
1
def show
-
@name = CGI.unescape(params[:id])
-
redirect_to project_wiki_index_path(@project) and return if @name == 'Home'
-
-
ref = params[:ref].presence || @wiki.ref
-
@page = @wiki.page(@name, ref)
-
if !@page && @wiki.page(@name)
-
flash[:error] = t('flash.wiki.ref_not_exist')
-
redirect_to project_wiki_path(@project, CGI.escape(@name)) and return
-
end
-
-
show_or_create_page
-
end
-
-
1
def edit
-
@name = CGI.unescape(params[:id])
-
if page = @wiki.page(@name)
-
@page = page
-
@content = page.text_data
-
render :edit
-
else
-
render :new
-
end
-
end
-
-
1
def update
-
@name = CGI.unescape(params[:id])
-
@page = @wiki.page(@name)
-
name = wiki_page_params[:rename] || @name
-
-
update_wiki_page(@wiki, @page, wiki_page_params[:content], {committer: committer}, name, wiki_page_params[:format])
-
update_wiki_page(@wiki, @page.footer, wiki_page_params[:footer], {committer: committer}) if wiki_page_params[:footer]
-
update_wiki_page(@wiki, @page.sidebar, wiki_page_params[:sidebar], {committer: committer}) if wiki_page_params[:sidebar]
-
-
committer.commit
-
-
flash[:notice] = t('flash.wiki.successfully_updated', name: @name)
-
redirect_to project_wiki_path(@project, CGI.escape(@name))
-
end
-
-
1
def new
-
@name = ''
-
@new = true
-
end
-
-
1
def create
-
@name = CGI.unescape(wiki_page_params[:page])
-
format = wiki_page_params[:format].intern
-
begin
-
@wiki.write_page(@name, format, wiki_page_params[:content] || '', {committer: committer}).commit
-
redirect_to project_wiki_path(@project, CGI.escape(@name))
-
rescue Gollum::DuplicatePageError => e
-
flash[:error] = t("flash.wiki.duplicate_page", name: @name)
-
render :new
-
end
-
end
-
-
1
def destroy
-
@name = CGI.unescape(params[:id])
-
page = @wiki.page(@name)
-
if page
-
@wiki.delete_page(page, {committer: committer}).commit
-
flash[:notice] = t("flash.wiki.page_successfully_removed")
-
else
-
flash[:notice] = t("flash.wiki.page_not_found", name: params[:id])
-
end
-
redirect_to project_wiki_index_path(@project)
-
end
-
-
1
def git
-
end
-
-
1
def compare
-
@name = CGI.unescape(params[:id])
-
if request.post?
-
@versions = params[:versions] || []
-
if @versions.size < 2
-
redirect_to history_project_wiki_path(@project, CGI.escape(@name))
-
else
-
redirect_to compare_versions_project_wiki_path(@project, CGI.escape(@name),
-
sprintf('%s...%s', @versions.last, @versions.first))
-
end
-
elsif request.get?
-
@versions = params[:versions].split(/\.{2,3}/)
-
if @versions.size < 2
-
redirect_to history_project_wiki_path(@project, CGI.escape(@name))
-
return
-
end
-
@page = @wiki.page(@name)
-
@diffs = [@wiki.repo.diff(@versions.first, @versions.last, @page.path).first]
-
render :compare
-
else
-
redirect_to project_wiki_path(@project, CGI.escape(@name))
-
end
-
end
-
-
1
def compare_wiki
-
if request.post?
-
@versions = params[:versions] || []
-
versions_string = case @versions.size
-
when 1 then @versions.first
-
when 2 then sprintf('%s...%s', @versions.last, @versions.first)
-
else begin
-
redirect_to history_project_wiki_index_path(@project)
-
return
-
end
-
end
-
redirect_to compare_versions_project_wiki_index_path(@project, versions_string)
-
elsif request.get?
-
@versions = params[:versions].split(/\.{2,3}/) || []
-
@diffs = case @versions.size
-
when 1 then @wiki.repo.commit_diff(@versions.first)
-
when 2 then @wiki.repo.diff(@versions.first, @versions.last)
-
else begin
-
redirect_to history_project_wiki_index_path(@project)
-
return
-
end
-
end
-
render :compare
-
else
-
redirect_to project_wiki_path(@project, CGI.escape(@name))
-
end
-
end
-
-
1
def revert
-
@name = CGI.unescape(params[:id])
-
@page = @wiki.page(@name)
-
sha1 = params[:sha1]
-
sha2 = params[:sha2]
-
sha2 = nil if params[:sha2] == 'prev'
-
-
if c = @wiki.revert_page(@page, sha1, sha2, {committer: committer}) and c.commit
-
flash[:notice] = t("flash.wiki.revert_success")
-
redirect_to project_wiki_path(@project, CGI.escape(@name))
-
else
-
# if revert wasn't successful then redirect back to comparsion.
-
# if second commit version is missed, then second version is
-
# params[:sha1] and first version is parent of params[:sha1]
-
# (see Gollum::Wiki#revert_page)
-
sha2, sha1 = sha1, "#{sha1}^" if !sha2
-
@versions = [sha1, sha2]
-
diffs = @wiki.repo.diff(@versions.first, @versions.last, @page.path)
-
@diffs = [diffs.first]
-
flash[:error] = t("flash.wiki.patch_does_not_apply")
-
render :compare
-
end
-
end
-
-
1
def revert_wiki
-
sha1 = params[:sha1]
-
sha2 = params[:sha2]
-
sha2 = nil if sha2 == 'prev'
-
if c = @wiki.revert_commit(sha1, sha2, {committer: committer}) and c.commit
-
flash[:notice] = t("flash.wiki.revert_success")
-
redirect_to project_wiki_index_path(@project)
-
else
-
sha2, sha1 = sha1, "#{sha1}^" if !sha2
-
@versions = [sha1, sha2]
-
@diffs = @wiki.repo.diff(@versions.first, @versions.last)
-
flash[:error] = t("flash.wiki.patch_does_not_apply")
-
render :compare
-
end
-
end
-
-
1
def preview
-
@name = wiki_page_params[:page]
-
@page = @wiki.preview_page(@name, wiki_page_params[:content], wiki_page_params[:format])
-
@content = @page.formatted_data
-
@editable = false
-
render :show
-
end
-
-
1
def history
-
@name = CGI.unescape(params[:id])
-
if @page = @wiki.page(@name)
-
@versions = @page.versions
-
else
-
redirect_back(fallback_location: '/')
-
end
-
end
-
-
1
def wiki_history
-
@versions = @wiki.log
-
render :history
-
end
-
-
1
def search
-
@query = params[:q]
-
@results = @wiki.search @query
-
end
-
-
1
def pages
-
@results = @wiki.pages
-
@ref = @wiki.ref
-
end
-
-
1
protected
-
-
1
def get_wiki
-
@wiki = Gollum::Wiki.new(@project.wiki_path,
-
WIKI_OPTIONS.merge(base_path: project_wiki_index_path(@project)))
-
end
-
-
# This method was grabbed from sinatra application, shipped with Gollum gem.
-
# See Gollum gem and Gollum License if you have any questions about license notes.
-
# https://github.com/github/gollum https://github.com/github/gollum/blob/master/LICENSE
-
1
def update_wiki_page(wiki, page, content, commit_msg, name = nil, format = nil)
-
return if !page ||
-
((!content || page.raw_data == content) && page.format == format)
-
name ||= page.name
-
format = (format || page.format).to_sym
-
content ||= page.raw_data
-
wiki.update_page(page, name, format, content.to_s, commit_msg)
-
end
-
-
1
def commit_message
-
msg = wiki_page_params[:message].presence
-
unless msg
-
msg = case action_name.to_s
-
when 'create' then "Created page #{@name.to_s}"
-
when 'update' then "Updated page #{@name.to_s}"
-
when 'destroy' then "Removed page #{@name.to_s}"
-
when 'revert' then "Reverted page #{@name.to_s}"
-
when 'revert_wiki' then "Reverted wiki"
-
end
-
msg << " (#{wiki_page_params[:format]})" if wiki_page_params[:format]
-
end
-
msg = 'Unhandled action' if !msg || msg.empty?
-
{ message: msg }
-
end
-
-
1
def committer
-
unless @committer
-
p = commit_message.merge({name: current_user.uname, email: current_user.email})
-
@committer = Gollum::Committer.new(@wiki, p)
-
GitHook.perform_later!(:notification, :process, {project_id: @project.id, actor_name: @committer.actor.name, commit_sha: @committer.commit})
-
end
-
@committer
-
end
-
-
1
def show_or_create_page
-
if @page
-
@content = @page.formatted_data
-
@editable = policy(@project).write?
-
render :show
-
elsif file = @wiki.file(@name)
-
render plain: file.raw_data, content_type: file.mime_type
-
elsif policy(@project).write?
-
@new = true
-
render :new
-
else
-
redirect_to action: :index #forbidden_path
-
end
-
end
-
-
1
def wiki_page_params
-
@wiki_page_params ||= params[:wiki_page] || {}
-
end
-
-
1
def authorize_read_actions
-
authorize @project, :show?
-
end
-
-
1
def authorize_write_actions
-
authorize @project, :write?
-
end
-
end
-
1
class RobotsController < ApplicationController
-
1
skip_after_action :verify_authorized
-
-
1
def index
-
render file: 'sitemap/robots', layout: false, content_type: Mime::TEXT
-
end
-
end
-
1
class SearchController < ApplicationController
-
1
include PaginateHelper
-
-
1
before_action :authenticate_user! unless APP_CONFIG['anonymous_access']
-
1
skip_after_action :verify_authorized
-
-
1
def index
-
@type = Search::TYPES.find{ |t| t == params[:type] } || Search::TYPES.first
-
@query = params[:query]
-
@search = Search.new(@query, current_user, paginate_params)
-
@collection = @search.send(@type)
-
end
-
end
-
1
class StatisticsController < ApplicationController
-
RANGES = [
-
1
RANGE_TWENTY_FOUR_HOURS = 'twenty_four_hours',
-
RANGE_LAST_7_DAYS = 'last_7_days',
-
RANGE_LAST_30_DAYS = 'last_30_days',
-
RANGE_LAST_60_DAYS = 'last_60_days',
-
RANGE_LAST_90_DAYS = 'last_90_days',
-
RANGE_LAST_180_DAYS = 'last_180_days',
-
RANGE_LAST_YEAR = 'last_year',
-
RANGE_CUSTOM = 'custom',
-
]
-
-
1
def index
-
authorize :statistic
-
respond_to do |format|
-
format.html
-
format.json do
-
init_variables
-
render json: StatisticPresenter.new(
-
range_start: @range_start,
-
range_end: @range_end,
-
unit: @unit,
-
users_or_groups: params[:users_or_groups]
-
)
-
end
-
end
-
end
-
-
1
private
-
-
1
def init_variables
-
case params[:range]
-
when RANGE_TWENTY_FOUR_HOURS
-
@range_end = Time.now.utc
-
@range_start = @range_end - 1.day
-
@unit = :hour
-
when RANGE_LAST_7_DAYS
-
@range_end = Date.today
-
@range_start = @range_end - 7.days
-
@unit = :day
-
when RANGE_LAST_30_DAYS
-
@range_end = Date.today
-
@range_start = @range_end - 30.days
-
@unit = :day
-
when RANGE_LAST_60_DAYS
-
@range_end = Date.today
-
@range_start = @range_end - 30.days
-
@unit = :day
-
when RANGE_LAST_90_DAYS
-
@range_end = Date.today
-
@range_start = @range_end - 90.days
-
@unit = :day
-
when RANGE_LAST_180_DAYS
-
@range_end = Date.today
-
@range_start = @range_end - 180.days
-
@unit = :month
-
when RANGE_LAST_YEAR
-
@range_end = Date.today
-
@range_start = @range_end - 1.year
-
@unit = :month
-
when RANGE_CUSTOM
-
@range_start = Time.zone.parse(params[:range_start]).utc
-
@range_end = Time.zone.parse(params[:range_end]).utc
-
diff = @range_end - @range_start
-
@unit =
-
if diff <= 24.hours
-
:hour
-
elsif diff <= 90.days
-
:day
-
else
-
:month
-
end
-
else
-
raise ActiveRecord::RecordNotFound
-
end
-
rescue ArgumentError
-
raise ActiveRecord::RecordNotFound
-
end
-
-
end
-
1
class Users::BaseController < ApplicationController
-
1
before_action :authenticate_user!
-
1
before_action :find_user
-
-
1
protected
-
-
1
def find_user
-
if user_id = params[:uname] || params[:user_id] || params[:id]
-
@user = User.opened.find_by_insensitive_uname! user_id
-
end
-
end
-
-
1
def set_current_user
-
@user = current_user
-
end
-
end
-
1
class Users::ProfileController < Users::BaseController
-
1
include PaginateHelper
-
-
1
skip_before_action :authenticate_user!, only: :show if APP_CONFIG['anonymous_access']
-
-
1
def show
-
authorize @user
-
respond_to do |format|
-
format.html do
-
@groups = @user.groups.order(:uname)
-
end
-
format.json do
-
@projects = @user.own_projects.search_like(params[:term]).recent
-
case params[:visibility]
-
when 'open'
-
@projects = @projects.opened
-
when 'hidden'
-
@projects = ProjectPolicy::Scope.new(current_user, @projects.by_visibilities('hidden')).read
-
else
-
@projects = ProjectPolicy::Scope.new(current_user, @projects).read
-
end
-
@total_items = @projects.count
-
@projects = @projects.paginate(paginate_params)
-
end
-
end
-
end
-
-
end
-
1
class Users::RegistrationsController < Devise::RegistrationsController
-
1
before_action :update_sanitized_params, if: :devise_controller?
-
1
before_action :check_captcha, only: [:create]
-
-
1
def new
-
super do |resource|
-
if params[:invite_key].to_s.strip.empty?
-
resource.invite_key = ''
-
else
-
invite = Invite.find_by_invite_key(params[:invite_key])
-
if !invite || invite.used?
-
flash[:error] = I18n.t('errors.messages.bad_invite_key')
-
resource.invite_key = ''
-
else
-
resource.invite_key = params[:invite_key]
-
end
-
end
-
end
-
end
-
-
1
def create
-
invite_key = params[:user][:invite_key]
-
invite = Invite.find_by_invite_key(invite_key)
-
if !invite || invite.used?
-
flash[:error] = I18n.t('errors.messages.bad_invite_key')
-
self.resource = resource_class.new sign_up_params
-
resource.validate
-
set_minimum_password_length
-
render :new
-
else
-
super do |r|
-
if r.persisted?
-
invite.invited_user = r
-
invite.save
-
end
-
end
-
end
-
end
-
-
1
protected
-
-
1
def update_sanitized_params
-
devise_parameter_sanitizer.for(:sign_up) do |u|
-
u.permit(:invite_key, :uname, :name, :email, :password, :password_confirmation)
-
end
-
end
-
-
1
private
-
-
1
def check_captcha
-
unless verify_recaptcha
-
self.resource = resource_class.new sign_up_params
-
resource.validate
-
set_minimum_password_length
-
render :new
-
end
-
end
-
end
-
1
class Users::SettingsController < Users::BaseController
-
1
include AvatarHelper
-
-
1
skip_before_action :find_user
-
-
1
before_action :set_current_user
-
1
before_action -> { authorize @user, :update? }
-
-
1
def profile
-
if request.patch?
-
send_confirmation = params[:user][:email] != @user.email
-
if @user.update_without_password(user_params)
-
update_avatar(@user, params)
-
if send_confirmation
-
@user.confirmed_at = @user.confirmation_sent_at = nil
-
@user.send_confirmation_instructions
-
end
-
flash[:notice] = t('flash.user.saved')
-
redirect_to profile_settings_path and return
-
end
-
flash[:error] = t('flash.user.save_error')
-
flash[:warning] = @user.errors.map(&:full_message).join('. ')
-
end
-
end
-
-
1
def reset_auth_token
-
@user.reset_authentication_token!
-
flash[:notice] = t("flash.user.reset_auth_token")
-
redirect_to profile_settings_path
-
end
-
-
1
def private
-
if request.patch?
-
if @user.update_with_password(user_params)
-
flash[:notice] = t('flash.user.saved')
-
redirect_to private_settings_path and return
-
end
-
flash[:error] = t('flash.user.save_error')
-
flash[:warning] = @user.errors.map(&:full_message).join('. ')
-
end
-
end
-
-
1
def invites
-
authorize :invite
-
@invites = Invite.owned(@user).order('id desc')
-
end
-
-
1
def create_invite
-
authorize :invite
-
invite = Invite.create(
-
user_id: @user.id
-
)
-
if invite.valid?
-
flash[:success] = I18n.t("flash.invite.created")
-
redirect_to invites_settings_path
-
else
-
flash[:error] = invite.errors.map(&:full_message).join('. ')
-
redirect_to invites_settings_path
-
end
-
end
-
-
1
def notifiers
-
if request.patch?
-
if @user.notifier.update(settings_notifier_params)
-
flash[:notice] = I18n.t("flash.settings.saved")
-
redirect_to notifiers_settings_path and return
-
end
-
flash[:error] = I18n.t("flash.settings.save_error")
-
end
-
end
-
-
1
def builds_settings
-
@user.builds_setting ||= @user.build_builds_setting
-
if request.patch?
-
if @user.builds_setting.update(user_builds_setting_params)
-
flash[:notice] = I18n.t("flash.settings.saved")
-
redirect_to builds_settings_settings_path and return
-
end
-
flash[:error] = I18n.t("flash.settings.save_error")
-
end
-
end
-
-
1
private
-
-
1
def settings_notifier_params
-
subject_params(SettingsNotifier)
-
end
-
-
1
def user_params
-
subject_params(User)
-
end
-
-
1
def user_builds_setting_params
-
subject_params(UserBuildsSetting)
-
end
-
-
end
-
1
class Users::SshKeysController < Users::BaseController
-
1
before_action :set_current_user
-
1
before_action -> { authorize current_user, :update? }
-
1
skip_before_action :find_user
-
-
1
def index
-
@ssh_key = SshKey.new
-
end
-
-
1
def create
-
@ssh_key = current_user.ssh_keys.new ssh_key_params
-
-
if @ssh_key.save
-
flash[:notice] = t 'flash.ssh_keys.saved'
-
else
-
flash[:error] = t 'flash.ssh_keys.save_error'
-
flash[:warning] = @ssh_key.errors.map(&:full_message).join('. ') unless @ssh_key.errors.empty?
-
end
-
redirect_to ssh_keys_path
-
end
-
-
1
def destroy
-
@ssh_key = current_user.ssh_keys.find params[:id]
-
if @ssh_key.destroy
-
flash[:notice] = t 'flash.ssh_keys.destroyed'
-
else
-
flash[:error] = t 'flash.ssh_keys.destroy_error'
-
end
-
redirect_to ssh_keys_path
-
end
-
-
1
private
-
-
1
def ssh_key_params
-
subject_params(SshKey)
-
end
-
-
end
-
1
class Users::UsersController < Users::BaseController
-
1
skip_before_action :authenticate_user!, only: [:allowed, :check, :discover]
-
1
skip_after_action :verify_authorized
-
1
before_action :find_user_by_key, only: [:allowed, :discover]
-
-
1
def allowed
-
project = Project.find_by_owner_and_name! params[:project]
-
pp = ProjectPolicy.new(@user, project)
-
can = case params[:action_type]
-
when 'git-upload-pack'
-
pp.read?
-
when 'git-receive-pack'
-
pp.write?
-
end
-
render inline: (!@user.access_locked? && can).to_s
-
end
-
-
1
def check
-
head :ok
-
end
-
-
1
def discover
-
render json: {name: @user.name}.to_json
-
end
-
-
1
protected
-
-
1
def find_user_by_key
-
key = SshKey.find(params[:key_id])
-
@user = key.user
-
end
-
end
-
1
module ActiveAdmin::AdminHelper
-
-
1
include ActiveAdmin::Views
-
-
1
def admin_polymorphic_path(resource)
-
self.send("admin_#{resource.class.to_s.underscore}_path", resource)
-
end
-
-
end
-
-
1
module ActivityFeedsHelper
-
1
def render_activity_feed(activity_feed)
-
render activity_feed.partial, activity_feed.data.merge(activity_feed: activity_feed)
-
end
-
-
1
def get_feed_title_from_content(content)
-
# removes html tags and haml generator indentation whitespaces and new line chars:
-
feed_title = strip_tags(content).gsub(/(^\s+|\n| )/, ' ')
-
# removes multiple whitespaces in a row and strip it:
-
feed_title = feed_title.gsub(/\s{2,}/, ' ').strip
-
end
-
-
1
def get_user_from_activity_item(item)
-
email = item.data[:creator_email]
-
User.where(email: email).first || User.new(email: email) if email.present?
-
end
-
-
1
def user_link(user, user_name, full_url = false)
-
user.persisted? ? link_to(user_name, full_url ? user_url(user) : user_path(user)) : user_name
-
end
-
-
1
def get_feed_build_list_status_message(status)
-
message, error = case status
-
when BuildList::BUILD_PENDING
-
['pending', nil]
-
when BuildList::BUILD_PUBLISHED
-
['published', nil]
-
when BuildList::SUCCESS
-
['success', nil]
-
else ['failed', t("layout.build_lists.statuses.#{BuildList::HUMAN_STATUSES[status]}")]
-
end
-
" #{t("notifications.bodies.build_status.#{message}", error: error)}"
-
end
-
end
-
1
module AdvisoriesHelper
-
1
def advisories_select_options(advisories, opts = {class: 'popoverable'})
-
def_values = [[t("layout.advisories.no_"), 'no'], [t("layout.advisories.new"), 'new'], [t("layout.advisories.existing"), 'existing', {class: 'advisory_id'}]]
-
options_for_select(def_values, def_values.first)
-
end
-
-
1
def advisory_id_for_hint
-
sprintf(Advisory::ID_STRING_TEMPLATE, type: "{#{Advisory::TYPES.values.join(',')}}",
-
year: 'YYYY', id: 'XXXX')
-
end
-
-
1
def construct_ref_link(ref)
-
ref = sanitize(ref)
-
url = if ref =~ %r[^http(s?)://*]
-
ref
-
else
-
'http://' << ref
-
end
-
link_to url, url
-
end
-
end
-
1
module ApplicationHelper
-
-
1
def submit_button_tag(icon_class: 'fa-check', text: nil)
-
text ||= I18n.t('layout.save')
-
button_tag type: :submit,
-
data: {'disable-with' => I18n.t('layout.processing')},
-
class: 'btn btn-primary' do
-
content_tag(:i, nil, class: ['fa', icon_class]) << ' '<< text
-
end
-
end
-
-
1
def layout_class
-
case
-
when controller_name == 'issues' && action_name == 'new'
-
'right nopadding'
-
when controller_name == 'build_lists' && ['new', 'create'].include?(action_name)
-
nil
-
when controller_name == 'platforms' && ['build_all', 'mass_builds'].include?(action_name)
-
'right slim'
-
when controller_name == 'platforms' && action_name == 'show'
-
'right bigpadding'
-
when controller_name == 'platforms' && action_name == 'clone'
-
'right middlepadding'
-
when controller_name == 'contacts' && action_name == 'sended'
-
'all feedback_sended'
-
else
-
content_for?(:sidebar) ? 'right' : 'all'
-
end
-
end
-
-
1
def top_menu_class(base)
-
(controller_name.include?('build_lists') ? controller_name : params[:controller]).include?(base.to_s) ? 'active' : nil
-
end
-
-
# Public: Get icon css class.
-
#
-
# base - the tab (Symbol).
-
#
-
# Returns String css class.
-
1
def top_menu_icon(base)
-
case base
-
when :platforms
-
'fa-linux'
-
when :projects
-
'fa-cube'
-
when :build_lists
-
'fa-cogs'
-
when :groups
-
'fa-users'
-
when :advisories
-
'fa-newspaper-o'
-
when :statistics
-
'fa-area-chart'
-
end
-
end
-
-
1
def title_object(object)
-
return object.advisory_id if object.class == Advisory
-
name = object.class == Group ? object.uname : object.name
-
object_name = t "activerecord.models.#{object.class.name.downcase}"
-
case object.class.name
-
when 'Project'
-
"#{object_name} #{object.owner.uname}/#{object.name}"
-
when 'Platform'
-
if object.main?
-
"#{object_name} #{object.name}"
-
else
-
"#{object_name} #{object.owner.uname}/#{object.name}"
-
end
-
when 'Repository', 'Product'
-
"#{object_name} #{object.name} - #{title_object object.platform}"
-
when 'Group'
-
"#{object_name} #{object.uname}"
-
else object.class.name
-
end
-
end
-
-
1
def local_alert(text, type = 'error')
-
html = "<div class='flash'><div class='alert #{type}'> #{text}"
-
html << link_to('×', '#', class: 'close close-alert', 'data-dismiss' => 'alert')
-
html << '</div></div>'
-
end
-
-
# Why 42? Because it is the Answer!
-
1
def short_message(message, length = 42)
-
truncate(message, length: length, omission: '…')
-
end
-
-
1
def datetime_moment(date, options = {})
-
tag = options[:tag] || :div
-
klass = "datetime_moment #{options[:class]}"
-
content_tag(tag, nil, class: klass, origin_datetime: date)
-
end
-
-
1
def alert_class(type)
-
case type
-
when 'error', 'alert'
-
'alert-danger'
-
when 'notice'
-
'alert-success'
-
else
-
"alert-#{type}"
-
end
-
end
-
-
1
def bytes_to_size(bytes)
-
sizes = [0, 1024, 1024*1024, 1024*1024*1024]
-
names = ['B', 'KiB', 'MiB', 'GiB']
-
sizes.each_with_index do |l, i|
-
low, high = sizes[i], sizes[i+1]
-
if bytes >= low && (!high || bytes < high)
-
if low == 0
-
sz = bytes
-
else
-
sz = (bytes.to_f / low).round(2)
-
end
-
return "#{sz}#{names[i]}"
-
end
-
end
-
end
-
end
-
1
module AvatarHelper
-
1
def update_avatar(subject, params)
-
if subject.avatar && params[:delete_avatar] == '1'
-
subject.avatar = nil
-
subject.save
-
end
-
end
-
end
-
1
module BuildListsHelper
-
-
# See: app/assets/javascripts/angularjs/models/build_list.js.erb
-
1
def build_list_status_color(status)
-
case status
-
when BuildList::BUILD_PUBLISHED, BuildList::SUCCESS, BuildList::BUILD_PUBLISHED_INTO_TESTING
-
'success'
-
when BuildList::BUILD_ERROR, BuildList::FAILED_PUBLISH, BuildList::REJECTED_PUBLISH, BuildList::FAILED_PUBLISH_INTO_TESTING, BuildList::PACKAGES_FAIL, BuildList::UNPERMITTED_ARCH
-
'error'
-
when BuildList::TESTS_FAILED
-
'warning'
-
else
-
'nocolor'
-
end
-
end
-
-
1
def can_run_dependent_build_lists?(build_list)
-
build_list.save_to_platform.main? &&
-
build_list.save_to_platform.distrib_type == 'mdv'
-
end
-
-
1
def availables_main_platforms
-
Platform.availables_main_platforms current_user
-
end
-
-
1
def dependent_projects(package)
-
return [] if package.dependent_packages.blank?
-
-
packages = BuildList::Package.
-
select('build_list_packages.project_id, build_list_packages.name').
-
joins(:build_list).
-
where(
-
platform_id: package.platform,
-
name: package.dependent_packages,
-
package_type: package.package_type,
-
build_lists: { status: BuildList::BUILD_PUBLISHED }
-
).
-
group('build_list_packages.project_id, build_list_packages.name').
-
reorder(:project_id).group_by(&:project_id)
-
-
Project.where(id: packages.keys).recent.map do |project|
-
[
-
project,
-
packages[project.id].map(&:name).sort
-
]
-
end
-
end
-
-
1
def external_nodes
-
BuildList::EXTERNAL_NODES.map do |type|
-
[I18n.t("layout.build_lists.external_nodes.#{type}"), type]
-
end
-
end
-
-
1
def auto_publish_statuses
-
BuildList::AUTO_PUBLISH_STATUSES.map do |status|
-
[I18n.t("layout.build_lists.auto_publish_status.#{status}"), status]
-
end
-
end
-
-
1
def mass_build_options
-
options_for_select(
-
MassBuild.recent.limit(15).pluck(:name, :id).unshift([t(:none), -1])
-
)
-
end
-
-
1
def build_list_options_for_new_core
-
[
-
[I18n.t("layout.true_"), 1],
-
[I18n.t("layout.false_"), 0]
-
]
-
end
-
-
1
def build_list_item_status_color(status)
-
case status
-
when BuildList::SUCCESS
-
'success'
-
when BuildList::BUILD_ERROR, BuildList::Item::GIT_ERROR #, BuildList::DEPENDENCIES_ERROR
-
'error'
-
else
-
''
-
end
-
end
-
-
1
def build_list_classified_update_types
-
advisoriable = BuildList::RELEASE_UPDATE_TYPES.map do |el|
-
[el, {class: 'advisoriable'}]
-
end
-
nonadvisoriable = (BuildList::UPDATE_TYPES - BuildList::RELEASE_UPDATE_TYPES).map do |el|
-
[el, {class: 'nonadvisoriable'}]
-
end
-
-
return advisoriable + nonadvisoriable
-
end
-
-
1
def build_list_item_version_link(item, str_version = false)
-
hash_size=5
-
if item.version =~ /^[\da-z]+$/ && item.name == item.build_list.project.name
-
bl = item.build_list
-
{
-
text: str_version ? "#{shortest_hash_id item.version, hash_size}" : shortest_hash_id(item.version, hash_size),
-
href: commit_path(bl.project, item.version)
-
}
-
else
-
{}
-
end
-
end
-
-
1
def build_list_version_name(bl)
-
hash_size=5
-
if bl.commit_hash.present?
-
if bl.last_published_commit_hash.present? && bl.last_published_commit_hash != bl.commit_hash
-
"#{shortest_hash_id bl.last_published_commit_hash, hash_size}...#{shortest_hash_id bl.commit_hash, hash_size}"
-
else
-
shortest_hash_id(bl.commit_hash, hash_size)
-
end
-
else
-
bl.project_version
-
end
-
end
-
-
1
def get_build_list_version_path(bl)
-
if bl.commit_hash.present?
-
if bl.last_published_commit_hash.present? && bl.last_published_commit_hash != bl.commit_hash
-
diff_path(bl.project, bl.last_published_commit_hash) + "...#{bl.commit_hash}"
-
else
-
commit_path(bl.project, bl.commit_hash)
-
end
-
else
-
nil
-
end
-
end
-
-
1
def build_list_version_link(bl)
-
hash_size=5
-
if bl.commit_hash.present?
-
if bl.last_published_commit_hash.present? && bl.last_published_commit_hash != bl.commit_hash
-
link_to "#{shortest_hash_id bl.last_published_commit_hash, hash_size}...#{shortest_hash_id bl.commit_hash, hash_size}",
-
diff_path(bl.project, bl.last_published_commit_hash) + "...#{bl.commit_hash}"
-
else
-
link_to shortest_hash_id(bl.commit_hash, hash_size), commit_path(bl.project, bl.commit_hash)
-
end
-
else
-
bl.project_version
-
end
-
end
-
-
1
def product_build_list_version_link(bl, str_version = false)
-
if bl.commit_hash.present?
-
link_to str_version ? "#{shortest_hash_id bl.commit_hash} ( #{bl.project_version} )" : shortest_hash_id(bl.commit_hash),
-
commit_path(bl.project, bl.commit_hash)
-
else
-
bl.project_version
-
end
-
end
-
-
1
def container_url(build_list = @build_list)
-
url = "#{APP_CONFIG['downloads_url']}/#{build_list.save_to_platform.name}/container/#{build_list.id}/"
-
if ['dnf', 'mdv'].include?(build_list.build_for_platform.try(:distrib_type))
-
url << "#{build_list.arch.name}/#{build_list.save_to_repository.name}/release/"
-
end
-
url.html_safe
-
end
-
-
1
def can_publish_in_future?(bl)
-
[
-
BuildList::SUCCESS,
-
BuildList::FAILED_PUBLISH,
-
BuildList::BUILD_PUBLISHED,
-
BuildList::TESTS_FAILED,
-
BuildList::BUILD_PUBLISHED_INTO_TESTING
-
].include?(bl.status)
-
end
-
-
1
def log_reload_time_options
-
t = I18n.t("layout.build_lists.log.reload_times").map { |i| i.reverse }
-
-
options_for_select(t, t.first).html_safe
-
end
-
-
1
def log_reload_lines_options
-
options_for_select([100, 200, 500, 1000, 1500, 2000], 1000).html_safe
-
end
-
-
1
def get_version_release build_list
-
pkg = build_list.source_packages.first
-
"#{pkg.version}-#{pkg.release}" if pkg.present?
-
end
-
-
1
def new_build_list_data(build_list, project, params)
-
res = {
-
build_list_id: params[:build_list_id],
-
name_with_owner: project.name_with_owner,
-
build_for_platform_id: params[:build_list].try(:[], :build_for_platform_id),
-
save_to_repository_id: save_to_repository_id(params),
-
project_version: project_version(project, params),
-
-
platforms: new_build_list_platforms(params),
-
save_to_repositories: save_to_repositories(project, params),
-
project_versions: build_list_project_versions(project),
-
arches: arches(params),
-
default_extra_repos: default_extra_repos(project),
-
extra_repos: extra_repos(params),
-
extra_build_lists: extra_build_lists(params),
-
auto_create_container: default_auto_create_container(params, build_list),
-
auto_publish_status: params[:build_list].try(:[], :auto_publish_status)
-
}
-
res.to_json
-
end
-
-
1
def is_repository_checked(repo, params)
-
include_repos(params).include? repo.id.to_s
-
end
-
-
1
def filter_by_save_to_platform
-
pls = availables_main_platforms
-
pls = pls.select{ |p| current_user_platforms.include?(p.id) } if current_user_platforms.present?
-
pls.map{ |pl| [pl.name, pl.id] }
-
end
-
-
1
private
-
-
1
def save_to_repositories(project, params)
-
project.repositories.map do |r|
-
# Show only main platforms which user used as default.
-
next if r.platform.main? && current_user_platforms.present? && current_user_platforms.exclude?(r.platform.id)
-
{
-
id: r.id,
-
name: "#{r.platform.name}/#{r.name}",
-
publish_without_qa: r.publish_without_qa?,
-
repo_name: r.name,
-
platform_id: r.platform.id,
-
default_branch: r.platform.default_branch,
-
default_arches: ( r.platform.platform_arch_settings.by_default.pluck(:arch_id).presence ||
-
Arch.where(name: Arch::DEFAULT).pluck(:id) )
-
}
-
end.compact.sort_by { |e| e[:name] }
-
end
-
-
1
def new_build_list_platforms(params)
-
availables_main_platforms.map do |pl|
-
# Show only main platforms which user used as default.
-
next if current_user_platforms.present? && current_user_platforms.exclude?(pl.id)
-
platform = { id: pl.id, name: pl.name, repositories: [] }
-
Repository.custom_sort(pl.repositories).each do |repo|
-
platform[:repositories] << { id: repo.id,
-
name: repo.name,
-
disabled: false,
-
checked: is_repository_checked(repo, params) }
-
end
-
platform
-
end.compact
-
end
-
-
1
def current_user_platforms
-
@current_user_platforms ||= (current_user.try(:builds_setting).try(:platforms) || []).select(&:present?).map(&:to_i)
-
end
-
-
1
def include_repos(params)
-
@include_repos ||= (params.try(:[], :build_list).try(:[], :include_repos) || []).map {|e| e.to_s}
-
end
-
-
1
def save_to_repository_id(params)
-
@save_to_repository_id ||= params[:build_list].try(:[], :save_to_repository_id).to_i
-
end
-
-
1
def project_version(project, params)
-
@project_version ||= params[:build_list].try(:[], :project_version) || project.resolve_default_branch
-
end
-
-
1
def build_list_project_versions(project)
-
return [] unless project
-
branches_kind = I18n.t('layout.git.repositories.branches')
-
tags_kind = I18n.t('layout.git.repositories.tags')
-
res = []
-
project.repo.branches.each do |br|
-
res << { name: br.name, kind: branches_kind }
-
end
-
project.repo.tags.each do |t|
-
res << { name: t.name, kind: tags_kind }
-
end
-
res.sort_by { |e| e[:name] }
-
end
-
-
1
def arches(params)
-
Arch.recent.map do |arch|
-
{
-
id: arch.id,
-
name: arch.name,
-
checked: (params[:arches]||[]).include?(arch.id) ||
-
(params[:arches].blank? &&
-
controller.action_name == 'new' &&
-
Arch::DEFAULT.include?(arch.name))
-
}
-
end
-
end
-
-
1
def default_extra_repos(project)
-
scope = project.repositories.joins(:platform).where(platforms: { platform_type: 'personal' })
-
scope = PlatformPolicy::Scope.new(current_user, scope).show
-
scope.map do |extra|
-
{
-
id: extra.id,
-
platform_id: extra.platform.id,
-
label: "#{extra.platform.name}/#{extra.name}",
-
path: url_for([extra.platform, extra])
-
}
-
end
-
end
-
-
1
def extra_repos(params)
-
Repository.where(id: params[:build_list].try(:[], :extra_repositories) ).map do |extra|
-
{
-
id: extra.id,
-
label: "#{extra.platform.name}/#{extra.name}",
-
path: url_for([extra.platform, extra])
-
}
-
end
-
end
-
-
1
def extra_build_lists(params)
-
BuildList.where(id: params[:build_list].try(:[], :extra_build_lists) ).map do |extra|
-
{
-
id: extra.id,
-
label: "#{extra.id} (#{extra.project.name} - #{extra.arch.name})",
-
path: url_for(extra)
-
}
-
end
-
end
-
-
1
def default_auto_create_container(params, build_list)
-
checked = params[:build_list].try(:[], :auto_create_container)
-
checked = build_list.auto_create_container if checked.nil?
-
checked
-
end
-
end
-
1
module CommentsHelper
-
1
def project_commentable_comment_path(project, commentable, comment)
-
if Comment.issue_comment?(commentable.class)
-
project_issue_comment_path(project, commentable, comment)
-
elsif Comment.commit_comment?(commentable.class)
-
project_commit_comment_path(project, commentable, comment)
-
end
-
end
-
-
1
def project_commentable_path(project, commentable)
-
if Comment.issue_comment?(commentable.class)
-
polymorphic_path [project, commentable.pull_request ? commentable.pull_request : commentable]
-
elsif Comment.commit_comment?(commentable.class)
-
commit_path project, commentable.id
-
end
-
end
-
-
1
def project_commentable_comments_path(project, commentable)
-
if commentable.is_a? Issue
-
project_issue_comments_path(@project, @commentable)
-
elsif commentable.is_a? Grit::Commit
-
project_commit_comments_path(@project, @commentable)
-
end
-
end
-
-
1
def comment_anchor c
-
"#{(c.data.present? && c.actual_inline_comment?) ? 'diff-' : ''}comment#{c.id}"
-
end
-
end
-
1
module CommitHelper
-
1
MAX_FILES_WITHOUT_COLLAPSE = 25
-
-
1
def render_commit_stats(options = {})
-
stats = options[:stats]
-
diff = options[:diff]
-
repo = options[:repo]
-
commit = options[:commit]
-
parent_commit = commit.parents.try(:first)
-
-
res = ["<ul class='list-group boffset0'>"]
-
ind=0
-
stats.files.each do |filename, adds, deletes, total|
-
file_name = get_filename_in_diff(diff[ind], filename)
-
file_status = t "layout.projects.diff.#{get_file_status_in_diff(diff[ind])}"
-
res << "<li class='list-group-item'>"
-
res << "<div class='row'>"
-
res << "<div class='col-sm-8'>"
-
res << "<a href='#diff-#{ind}' data-toggle='tooltip' data-placement='top' title='#{file_status}'>"
-
res << "#{diff_file_icon(diff[ind])} #{h(file_name)}"
-
res << "</a></div>"
-
res << render_file_changes(diff: diff[ind], adds: adds, deletes: deletes, total: total,
-
repo: repo, commit: commit, parent_commit: parent_commit, file_status: file_status)
-
res << "</div"
-
res << "</li>"
-
ind +=1
-
end
-
res << "</ul>"
-
-
wrap_commit_header_list(stats, res)
-
end
-
-
1
def wrap_commit_header_list(stats, list)
-
is_stats_open = stats.files.count <= MAX_FILES_WITHOUT_COLLAPSE ? 'in' : ''
-
res = ["<div class='panel-group' id='diff_header' role='tablist' aria-multiselectable='false'>"]
-
res << "<div class='panel panel-default'>"
-
res << "<div class='panel-heading' role='tab' id='heading'>"
-
res << "<h4 class='panel-title'>"
-
res << "<a data-toggle='collapse' data-parent='#diff_header' href='#collapseList' aria-expanded='true' aria-controls='collapseList'>"
-
res << "<span class='fa fa-chevron-#{is_stats_open ? 'down' : 'up'}'></span>"
-
res << " #{diff_commit_header_message(stats)}</a>"
-
res << "</h4>"
-
res << "</div>"
-
res << "<div id='collapseList' class='panel-collapse collapse #{is_stats_open}' role='tabpanel' aria-labelledby='collapseList'>"
-
res << "<div class='panel-body'>"
-
res += list
-
res << "</div>"
-
res << "</div>"
-
res << "</div>"
-
res << "</div>"
-
res.join("\n").html_safe
-
end
-
-
1
def diff_commit_header_message(stats)
-
t("layout.projects.diff_show_header",
-
files: t("layout.projects.commit_files_count", count: stats.files.size),
-
additions: t("layout.projects.commit_additions_count", count: stats.additions),
-
deletions: t("layout.projects.commit_deletions_count", count: stats.deletions))
-
end
-
-
1
def commit_date(date)
-
I18n.localize(date, { format: "%d %B %Y" })
-
end
-
-
1
def short_hash_id(id)
-
id[0..19]
-
end
-
-
1
def shortest_hash_id(id, size=10)
-
id[0..size-1]
-
end
-
-
1
def commit_author_link(author)
-
name = author.name
-
email = author.email
-
u = User.where(email: email).first
-
u.present? ? link_to(name, user_path(u)) : mail_to(email, name)
-
end
-
-
1
def commits_pluralize(commits_count)
-
Russian.p(commits_count, *commits_pluralization_arr)
-
end
-
-
1
def is_file_open_in_diff(blob, diff)
-
return true if blob.binary? && blob.render_as == :image
-
return true if diff.diff.blank? && diff.a_mode != diff.b_mode
-
diff.diff.present? && diff.diff.split("\n").count <= DiffHelper::MAX_LINES_WITHOUT_COLLAPSE
-
end
-
-
1
def file_blob_in_diff(repo, commit_id, diff)
-
return if repo.nil? || commit_id.nil? || diff.nil?
-
tree = repo.tree(commit_id)
-
blob = diff.renamed_file ? (tree / diff.b_path) : (tree / (diff.a_path || diff.b_path))
-
blob || diff.a_blob || diff.b_blob
-
end
-
-
1
def get_commit_id_for_file(diff, commit, parent_commit)
-
diff.deleted_file ? parent_commit.id : commit.id
-
end
-
-
1
def get_file_status_in_diff(diff)
-
if diff.renamed_file
-
:renamed_file
-
elsif diff.new_file
-
:new_file
-
elsif diff.deleted_file
-
:deleted_file
-
else
-
:changed_file
-
end
-
end
-
-
1
def get_filename_in_diff(diff, filename)
-
if diff.renamed_file
-
"#{diff.a_path.rtruncate 50} => #{diff.b_path.rtruncate 50}"
-
else
-
filename.rtruncate(100)
-
end
-
end
-
-
1
protected
-
-
1
def commits_pluralization_arr
-
pluralize ||= t('layout.commits.pluralize').map {|base, title| title.to_s}
-
end
-
-
1
def render_file_changes(options = {})
-
diff = options[:diff]
-
adds = options[:adds]
-
deletes = options[:deletes]
-
total = options[:total]
-
repo = options[:repo]
-
file_status = options[:file_status]
-
commit_id = get_commit_id_for_file(diff, options[:commit], options[:parent_commit])
-
blob = file_blob_in_diff(repo, commit_id, diff)
-
-
res = ''
-
res << "<div class='col-sm-3'>"
-
res << "<div class='pull-right'>"
-
if blob.binary?
-
res << "<strong class='text-primary'>#{t 'layout.projects.diff.binary'} #{file_status}</strong>"
-
elsif total > 0
-
res << "<strong class='text-success'>+#{adds}</strong> <strong class='text-danger'>-#{deletes}</strong>"
-
else # total == 0
-
res << "<strong class='text-primary'>#{t 'layout.projects.diff.without_changes'}</strong>"
-
end
-
res << "</div>"
-
res << "</div>"
-
-
res << "<div class='col-sm-1'>"
-
res << render_progress_bar(adds, deletes, total, blob)
-
res << "</div>"
-
-
end
-
-
1
def render_progress_bar(adds, deletes, total, blob)
-
res = ''
-
pluses = 0
-
minuses = 0
-
-
if total > 0
-
pluses = ((adds/(adds+deletes).to_f)*100).round
-
minuses = 100 - pluses
-
end
-
-
title = if total >0
-
t 'layout.projects.inline_changes_count', count: total
-
elsif !blob.binary?
-
t 'layout.projects.diff.without_changes'
-
else
-
'BIN'
-
end
-
-
res << "<div class='progress' style='margin-bottom: 0' data-toggle='tooltip' data-placement='top' title='#{title}'>"
-
res << "<div class='progress-bar progress-bar-success' style='width: #{pluses}%'></div>"
-
res << "<div class='progress-bar progress-bar-danger' style='width: #{minuses}%'></div>"
-
res << "</div>"
-
res
-
end
-
-
1
def diff_file_icon(diff)
-
icon = case get_file_status_in_diff(diff)
-
when :renamed_file
-
'fa-caret-square-o-right text-info'
-
when :new_file
-
'fa-plus-square text-success'
-
when :deleted_file
-
'fa-minus-square text-danger'
-
when :changed_file
-
'fa-pencil-square text-primary'
-
else
-
'fa-exclamation-circle text-danger'
-
end
-
"<i class='fa #{icon}'></i>"
-
end
-
end
-
1
module DatatableHelper
-
1
def page
-
(params[:iDisplayStart].to_i/(params[:iDisplayLength].present? ? params[:iDisplayLength] : 25).to_i).to_i + 1
-
end
-
-
1
def per_page
-
params[:iDisplayLength].present? ? params[:iDisplayLength] : 25
-
end
-
-
1
def sort_dir
-
params[:sSortDir_0] == 'asc' ? 'asc' : 'desc'
-
end
-
-
end
-
1
module DeviseHelper
-
1
def getDeviseErrors(*name)
-
res = Array.new(name.count)
-
resource.errors.each do |attr, message|
-
if index = name.index(attr)
-
res[index] = message
-
end
-
end
-
res
-
end
-
-
1
def showDeviseHintError(name, error, additional_class = '')
-
if error
-
"<div id='hint' class='error #{name.to_s} #{additional_class}' style='display: block;'> \
-
<div class='img'></div> \
-
<div class='msg'> #{error}</div> \
-
</div>".html_safe
-
end
-
end
-
end
-
1
module DiffHelper
-
1
include CommitHelper
-
-
1
MAX_LINES_WITHOUT_COLLAPSE = 50
-
-
1
def render_diff_stats(options = {})
-
stats = options[:stats]
-
diff = options[:diff]
-
repo = options[:repo]
-
commit = options[:commit]
-
parent_commit = options[:common_ancestor]
-
-
res = ["<ul class='list-group boffset0'>"]
-
stats.each_with_index do |stat, ind|
-
adds = stat.additions
-
deletes = stat.deletions
-
total = adds + deletes
-
file_name = get_filename_in_diff(diff[ind], stat.filename)
-
file_status = t "layout.projects.diff.#{get_file_status_in_diff(diff[ind])}"
-
-
res << "<li class='list-group-item'>"
-
res << "<div class='row'>"
-
res << "<div class='col-sm-8'>"
-
res << "<a href='#diff-#{ind}' data-toggle='tooltip' data-placement='top' title='#{file_status}'>"
-
res << "#{diff_file_icon(diff[ind])} #{h(file_name)}"
-
res << "</a></div>"
-
res << render_file_changes(diff: diff[ind], adds: adds, deletes: deletes, total: total,
-
repo: repo, commit: commit, parent_commit: parent_commit, file_status: file_status)
-
res << "</div"
-
res << "</li>"
-
ind +=1
-
end
-
res << "</ul>"
-
-
wrap_diff_header_list(stats, res)
-
end
-
-
1
def wrap_diff_header_list(stats, list)
-
is_stats_open = stats.count <= MAX_FILES_WITHOUT_COLLAPSE ? 'in' : ''
-
res = ["<div class='panel-group' id='diff_header' role='tablist' aria-multiselectable='false'>"]
-
res << "<div class='panel panel-default'>"
-
res << "<div class='panel-heading' role='tab' id='heading'>"
-
res << "<h4 class='panel-title'>"
-
res << "<a data-toggle='collapse' data-parent='#diff_header' href='#collapseList' aria-expanded='true' aria-controls='collapseList'>"
-
res << "<span class='fa fa-chevron-#{is_stats_open ? 'down' : 'up'}'></span>"
-
res << " #{diff_header_message(stats)}</a>"
-
res << "</h4>"
-
res << "</div>"
-
res << "<div id='collapseList' class='panel-collapse collapse #{is_stats_open}' role='tabpanel' aria-labelledby='collapseList'>"
-
res << "<div class='panel-body'>"
-
res += list
-
res << "</div>"
-
res << "</div>"
-
res << "</div>"
-
res << "</div>"
-
res.join("\n").html_safe
-
end
-
-
1
def diff_header_message(stats)
-
total_additions = stats.inject(0) {|sum, n| sum + n.additions}
-
total_deletions = stats.inject(0) {|sum, n| sum + n.deletions}
-
I18n.t('layout.projects.diff_show_header',
-
files: t('layout.projects.commit_files_count', count: stats.count),
-
additions: t('layout.projects.commit_additions_count', count: total_additions),
-
deletions: t('layout.projects.commit_deletions_count', count: total_deletions))
-
end
-
-
#include Git::Diff::InlineCallback
-
1
def render_diff(diff, args = {})#diff_counter, comments, opts = nil diffpath = nil)
-
if diff.respond_to?(:diff)
-
diff, filepath, in_discussion = diff.diff, diff.a_path, false
-
comments = (args[:comments] || []).select{|c| c.data.try('[]', :path) == filepath}
-
else
-
filepath, in_discussion, comments = args[:diffpath], true, args[:comments]
-
end
-
-
diff_display ||= Diff::Display::Unified.new(diff)
-
url = if @pull
-
@pull.id ? polymorphic_path([@project, @pull]) : ''
-
elsif @commit
-
commit_path @project, @commit
-
end
-
prepare(args.merge({filepath: filepath, comments: comments, in_discussion: in_discussion}))
-
-
res = '<div class="table-responsive overflow-auto">'
-
res << '<table class="table diff inline table-borderless" cellspacing="0" cellpadding="0">'
-
res << '<tbody>'
-
res << renderer(diff_display.data) #diff_display.render(Git::Diff::InlineCallback.new comments, path)
-
res << tr_line_comments(comments) if in_discussion
-
res << '</tbody>'
-
res << '</table>'
-
res << '</div>'
-
res.html_safe
-
end
-
-
########################################################
-
# FIXME: Just to dev, remove to lib. Really need it?
-
########################################################
-
1
def prepare(args)
-
@url, @diff_counter, @in_discussion = args[:url], args[:diff_counter], args[:in_discussion]
-
@filepath, @line_comments = args[:filepath], args[:comments]
-
@diff_prefix = args[:diff_prefix] || 'diff'
-
@add_reply_id, @num_line = if @in_discussion
-
[@line_comments[0].id, @line_comments[0].data[:line].to_i - @line_comments[0].data[:strings].lines.count.to_i-1]
-
else
-
[nil, -1]
-
end
-
-
@no_commit_comment = true if params[:controller] == 'projects/wiki' || (params[:action] == 'diff')
-
end
-
-
1
def headerline(line)
-
set_line_number
-
"<tr class='header'>
-
<td class='line_numbers'>...</td>
-
<td class='line_numbers'>...</td>
-
<td class='header'>#{line}</td>
-
</tr>"
-
end
-
-
1
def addline(line)
-
set_line_number
-
"<tr class='changes'>
-
<td class='line_numbers'></td>
-
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number}
-
<td class='code ins'>
-
#{line_comment_icon}
-
<pre ng-non-bindable>#{render_line(line)}</pre>
-
</td>
-
</tr>
-
#{render_line_comments}"
-
end
-
-
1
def remline(line)
-
set_line_number
-
"<tr class='changes'>
-
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number}
-
<td class='line_numbers'></td>
-
<td class='code del'>
-
#{line_comment_icon}
-
<pre ng-non-bindable>#{render_line(line)}</pre>
-
</td>
-
</tr>
-
#{render_line_comments}"
-
end
-
-
1
def modline(line)
-
set_line_number
-
"<tr class='changes line'>
-
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number}
-
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number}
-
<td class='code unchanged modline'>
-
#{line_comment_icon}
-
<pre ng-non-bindable>#{render_line(line)}</pre>
-
</td>
-
</tr>
-
#{render_line_comments}"
-
end
-
-
1
def unmodline(line)
-
set_line_number
-
"<tr class='changes unmodline'>
-
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number}
-
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number}
-
<td class='code unchanged unmodline'>
-
#{line_comment_icon}
-
<pre ng-non-bindable>#{render_line(line)}</pre>
-
</td>
-
</tr>
-
#{render_line_comments}"
-
end
-
-
1
def sepline(line)
-
"<tr class='changes hunk-sep'>
-
<td class='line_numbers line_num_cut'>…</td>
-
<td class='line_numbers line_num_cut'>…</td>
-
<td class='code cut-line'></td>
-
</tr>"
-
end
-
-
1
def nonewlineline(line)
-
set_line_number
-
"<tr class='changes'>
-
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}L#{line.old_number}", line.old_number}
-
#{td_line_link "#{@diff_prefix}-F#{@diff_counter}R#{line.new_number}", line.new_number}
-
<td class='code modline unmodline'>
-
#{line_comment_icon}
-
<pre ng-non-bindable>#{render_line(line)}</pre>
-
</td>
-
</tr>
-
#{render_line_comments}"
-
end
-
-
1
def before_headerblock(block)
-
end
-
-
1
def after_headerblock(block)
-
end
-
-
1
def before_unmodblock(block)
-
end
-
-
1
def before_modblock(block)
-
end
-
-
1
def before_remblock(block)
-
end
-
-
1
def before_addblock(block)
-
end
-
-
1
def before_sepblock(block)
-
end
-
-
1
def before_nonewlineblock(block)
-
end
-
-
1
def after_unmodblock(block)
-
end
-
-
1
def after_modblock(block)
-
end
-
-
1
def after_remblock(block)
-
end
-
-
1
def after_addblock(block)
-
end
-
-
1
def after_sepblock(block)
-
end
-
-
1
def after_nonewlineblock(block)
-
end
-
-
1
def new_line
-
""
-
end
-
-
1
def renderer(data)
-
result = []
-
data.each do |block|
-
result << send("before_" + classify(block), block)
-
result << block.map { |line| send(classify(line), line) }
-
result << send("after_" + classify(block), block)
-
end
-
result.compact.join(new_line)
-
end
-
-
1
protected
-
-
1
def classify(object)
-
object.class.name[/\w+$/].downcase
-
end
-
-
1
def escape(str)
-
str.to_s.gsub('&', '&').gsub('<', '<').gsub('>', '>').gsub('"', '"')
-
end
-
-
1
def render_line(line)
-
res = '<span class="diff-content">'
-
if line.inline_changes?
-
prefix, changed, postfix = line.segments.map{|segment| escape(segment) }
-
res << "#{prefix}<span class='idiff'>#{changed}</span>#{postfix}"
-
else
-
res << escape(line)
-
end
-
res << '</span>'
-
-
res
-
end
-
-
1
def set_line_number
-
@num_line = @num_line.succ
-
end
-
-
1
def line_comment_icon
-
return if @no_commit_comment || (@in_discussion && @add_reply_id && @line_comments[0].data[:line].to_i != @num_line)
-
if current_user
-
link_to image_tag('line_comment.png', alt: t('layout.comments.new_header')),
-
'#new_inline_comment',
-
class: 'add_line-comment',
-
'ng-click' => "commentsCtrl.showInlineForm($event, #{new_inline_comment_params.to_json})"
-
end
-
end
-
-
1
def render_line_comments
-
unless @no_commit_comment || @in_discussion
-
comments = @line_comments.select do |c|
-
c.data.try('[]', :line).to_s == @num_line.to_s && c.actual_inline_comment?
-
end
-
tr_line_comments(comments) if comments.count > 0
-
end
-
end
-
-
1
def td_line_link id, num
-
"<td class='line_numbers' id='#{id}'><a href='#{@url}##{id}'>#{num}</a></td>"
-
end
-
-
1
def tr_line_comments comments
-
return if @no_commit_comment
-
res="<tr class='line-comments'>
-
<td class='line_numbers' colspan='2'>#{comments.count}</td>
-
<td>"
-
comments.each do |comment|
-
res << "<div class='line-comment'>
-
#{render 'projects/comments/comment', comment: comment, data: {project: @project, commentable: @commentable, add_anchor: 'inline', in_discussion: @in_discussion}}
-
</div>"
-
end
-
if current_user
-
res << link_to( t('layout.comments.new_inline'),
-
'#new_inline_comment',
-
class: 'btn btn-primary',
-
'ng-click' => "commentsCtrl.showInlineForm($event, #{new_inline_comment_params.to_json})",
-
'ng-hide' => "commentsCtrl.hideInlineCommentButton(#{new_inline_comment_params.to_json})" )
-
end
-
res << "</td></tr>"
-
end
-
# def new_comment_path
-
# hash = {path: @filepath, line: @num_line}
-
# if @commentable.is_a? Issue
-
# project_new_line_pull_comment_path(@project, @commentable, hash.merge({in_reply: @add_reply_id}))
-
# elsif @commentable.is_a? Grit::Commit
-
# new_line_commit_comment_path(@project, @commentable, hash)
-
# end
-
# end
-
-
1
def new_inline_comment_params
-
{ path: @filepath, line: @num_line, in_reply: @add_reply_id }
-
end
-
-
end
-
1
module FileStoreHelper
-
-
1
def file_store_results_url(sha1, file_name)
-
url = "#{APP_CONFIG['file_store_url']}/api/v1/file_stores/#{sha1}"
-
url << '.log?show=true' if file_name =~ /.*\.(log|txt)$/ || file_name =~ /.*\.(log.gz|txt.gz)/
-
url
-
end
-
-
1
def link_to_file_store(file_name, sha1)
-
if sha1.present?
-
link_to file_name, file_store_results_url(sha1, file_name)
-
else
-
I18n.t('layout.no_')
-
end
-
end
-
-
end
-
1
module GitHelper
-
-
1
def submodule_url(node, treeish)
-
# node.url(treeish) looks like:
-
# - http://0.0.0.0:3000/abf/git@abf.rosalinux.ru:abf/rhel-scripts.git
-
# - git://github.com/avokhmin/mdv-scripts.git
-
# - empty string if ".gitmodules" does not exist
-
url = node.url(treeish)
-
return nil if url.blank?
-
url.gsub!(/.git$/, '')
-
if url =~ /^git:/
-
url.gsub!(/^git/, 'http')
-
elsif str = /git@.*:.*/.match(url)
-
str = str[0].gsub(/^git@/, '')
-
domen = str.gsub(/:.*/, '')
-
owner = str.gsub(/^#{domen}:/, '').gsub(/\/.*/, '')
-
project = str.gsub(/.*\//, '')
-
url = "http://#{domen}/#{owner}/#{project}"
-
end
-
url
-
end
-
-
1
def render_path
-
# TODO: Looks ugly, rewrite with clear mind.
-
if @path.present?
-
if @treeish == @project.resolve_default_branch
-
res = "#{link_to @project.name, tree_path(@project)} / "
-
else
-
res = "#{link_to @project.name, tree_path(@project, @treeish)} / "
-
end
-
-
parts = @path.split("/")
-
-
current_path = parts.first
-
res << (parts.length == 1 ? parts.first : link_to(parts.first, tree_path(@project, @treeish, current_path)) + " / ")
-
-
parts[1..-2].each do |part|
-
current_path = File.join([current_path, part].compact)
-
res << link_to(part, tree_path(@project, @treeish, current_path))
-
res << " / "
-
end
-
-
res << parts.last if parts.length > 1
-
else
-
res = "#{link_to @project.name, tree_path(@project)} /"
-
end
-
-
res.html_safe
-
end
-
-
1
def render_line_numbers(n)
-
res = ""
-
1.upto(n){ |i| res << "<span id='L#{i}'><a href='#L#{i}'>#{i}</a></span><br/>" }
-
-
res.html_safe
-
end
-
-
1
def iterate_path(path)
-
tree = []
-
path.split("\/").each do |name|
-
if tree.last
-
tree << [File.join(tree.try(:last).try(:first), name), name]
-
else
-
tree << [name, name]
-
end
-
end
-
tree
-
end
-
-
1
def branch_selector_options(project)
-
p, tag_enabled = params.dup.to_unsafe_h, !(controller_name == 'trees' && action_name == 'branches')
-
p.delete(:path) if p[:path].present? # to root path
-
p.merge!(project_id: project.id, treeish: project.resolve_default_branch).delete(:id) unless p[:treeish].present?
-
current = url_for(p).split('?', 2).first
-
-
res = []
-
if params[:treeish].present? && !project.repo.branches_and_tags.map(&:name).include?(params[:treeish])
-
res << [I18n.t('layout.git.repositories.commits'), [params[:treeish].truncate(20)]]
-
end
-
linking = Proc.new {|name| [name.truncate(20), url_for(p.merge treeish: name).split('?', 2).first]}
-
res << [I18n.t('layout.git.repositories.branches'), project.repo.branches.map(&:name).sort.map(&linking)]
-
if tag_enabled
-
res << [I18n.t('layout.git.repositories.tags'), project.repo.tags.map(&:name).sort.map(&linking)]
-
else
-
res << [I18n.t('layout.git.repositories.tags'), project.repo.tags.map(&:name).sort.map {|name| [name.truncate(20), {disabled: true}]}]
-
end
-
grouped_options_for_select(res, current)
-
end
-
-
1
def versions_for_group_select(project)
-
return [] unless project
-
[
-
[I18n.t('layout.git.repositories.branches'), project.repo.branches.map(&:name).sort],
-
[I18n.t('layout.git.repositories.tags'), project.repo.tags.map(&:name).sort]
-
]
-
end
-
-
1
def split_commits_by_date(commits)
-
commits.inject({}) do |h, commit|
-
dt = commit.committed_date
-
h[dt.year] ||= {}
-
h[dt.year][dt.month] ||= {}
-
h[dt.year][dt.month][dt.day] ||= []
-
h[dt.year][dt.month][dt.day] << commit
-
h
-
end
-
end
-
-
1
def blob_highlight(blob, path)
-
return if blob.nil? || blob.size == 0
-
rugged = blob.repo.rugged
-
lazy = Linguist::LazyBlob.new(rugged, blob.id, path, blob.mode)
-
language = lazy.language
-
lexer = nil
-
if language
-
lexer = Pygments::Lexer.find_by_name(language.name)
-
if !lexer
-
language.aliases.each do |al|
-
lexer = Pygments::Lexer.find_by_alias(al)
-
break if lexer
-
end
-
end
-
lexer = Pygments::Lexer.find('spec') if language.name == 'RPM Spec'
-
end
-
lexer = Pygments::Lexer.find('Text') if !lexer
-
result = lexer.highlight rugged.lookup(blob.id).text, highlight_options
-
result.present? ? result.html_safe : text
-
rescue => e
-
"<pre>#{blob.data}</pre>".html_safe
-
end
-
-
1
def blame_highlight(blob, path, text)
-
return if blob.nil? || text.blank?
-
rugged = blob.repo.rugged
-
lazy = Linguist::LazyBlob.new(rugged, blob.id, path, blob.mode)
-
language = lazy.language
-
lexer = nil
-
if language
-
lexer = Pygments::Lexer.find_by_name(language.name)
-
if !lexer
-
language.aliases.each do |al|
-
lexer = Pygments::Lexer.find_by_alias(al)
-
break if lexer
-
end
-
end
-
lexer = Pygments::Lexer.find('spec') if language.name == 'RPM Spec'
-
end
-
lexer = Pygments::Lexer.find('Text') if !lexer
-
result = lexer.highlight(text)
-
result.present? ? result.html_safe : text
-
rescue => e
-
puts e
-
"<pre>#{text}</pre>".html_safe
-
end
-
-
1
protected
-
-
1
def highlight_options
-
@highlight ||= { options: { linenos: true, lineanchors: 'lc', linespans: 'ln', anchorlinenos: true }}
-
end
-
end
-
# This module is based on
-
# https://github.com/gitlabhq/gitlabhq/blob/7665b1de7eed4addd7b94786c84e6674710e6377/app/helpers/gitlab_markdown_helper.rb
-
1
module GitlabMarkdownHelper
-
1
include MarkdownHelper
-
-
# Use this in places where you would normally use link_to(gfm(...), ...).
-
#
-
# It solves a problem occurring with nested links (i.e.
-
# "<a>outer text <a>gfm ref</a> more outer text</a>"). This will not be
-
# interpreted as intended. Browsers will parse something like
-
# "<a>outer text </a><a>gfm ref</a> more outer text" (notice the last part is
-
# not linked any more). link_to_gfm corrects that. It wraps all parts to
-
# explicitly produce the correct linking behavior (i.e.
-
# "<a>outer text </a><a>gfm ref</a><a> more outer text</a>").
-
1
def link_to_gfm(body, url, html_options = {})
-
return "" if body.blank?
-
-
escaped_body = if body =~ /^\<img/
-
body
-
else
-
escape_once(body)
-
end
-
-
gfm_body = gfm(escaped_body, html_options)
-
-
gfm_body.gsub!(%r{<a.*?>.*?</a>}m) do |match|
-
"</a>#{match}#{link_to("", url, html_options)[0..-5]}" # "</a>".length +1
-
end
-
-
link_to(gfm_body.html_safe, url, html_options)
-
end
-
-
1
def markdown(text)
-
return '' if text.blank?
-
unless @markdown
-
gitlab_renderer = Redcarpet::Render::GitlabHTML.new(self,
-
# see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch-
-
filter_html: true,
-
with_toc_data: true,
-
hard_wrap: true)
-
@markdown = Redcarpet::Markdown.new(gitlab_renderer,
-
# see https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
-
no_intra_emphasis: true,
-
tables: true,
-
fenced_code_blocks: true,
-
autolink: true,
-
strikethrough: true,
-
lax_html_blocks: true,
-
space_after_headers: true,
-
superscript: true)
-
end
-
-
@markdown.render(text).html_safe
-
end
-
-
1
def create_relative_links(text)
-
paths = extract_paths(text)
-
-
paths.uniq.each do |file_path|
-
new_path = rebuild_path(file_path)
-
# Finds quoted path so we don't replace other mentions of the string
-
# eg. "doc/api" will be replaced and "/home/doc/api/text" won't
-
text.gsub!("\"#{file_path}\"", "\"/#{new_path}\"")
-
end
-
-
text
-
end
-
-
1
def extract_paths(text)
-
links = substitute_links(text)
-
image_links = substitute_image_links(text)
-
links + image_links
-
end
-
-
1
def substitute_links(text)
-
links = text.scan(/<a href=\"([^"]*)\">/)
-
relative_links = links.flatten.reject{ |link| link_to_ignore? link }
-
relative_links
-
end
-
-
1
def substitute_image_links(text)
-
links = text.scan(/<img src=\"([^"]*)\"/)
-
relative_links = links.flatten.reject{ |link| link_to_ignore? link }
-
relative_links
-
end
-
-
1
def link_to_ignore?(link)
-
ignored_protocols.map{ |protocol| link.include?(protocol) }.any?
-
end
-
-
1
def ignored_protocols
-
["http://","https://", "ftp://", "mailto:"]
-
end
-
-
1
def render_wiki_content(wiki_page)
-
if wiki_page.format == :markdown
-
markdown(wiki_page.content)
-
else
-
wiki_page.formatted_content.html_safe
-
end
-
end
-
end
-
1
module IssuesHelper
-
1
def tracker_search_field(name, txt, classes = nil)
-
str = "<input name='#{name}' id='#{name}' type='text' value='#{txt}'"
-
str << "onblur=\"if(this.value==''){this.value='#{txt}';this.className='gray #{classes}';}\""
-
str << "onclick=\"if(this.value=='#{txt}'){this.value='';this.className='black #{classes}';}\" class=\"gray #{classes}\">"
-
str.html_safe
-
end
-
end
-
1
module KeyPairsHelper
-
-
1
def key_pair_repository_options(platform)
-
platform.repositories.map do |r|
-
[r.name, r.id]
-
end
-
end
-
end
-
# This module is based on
-
# https://github.com/gitlabhq/gitlabhq/blob/397c3da9758c03a215a308c011f94261d9c61cfa/lib/gitlab/markdown.rb
-
-
# Custom parser for GitLab-flavored Markdown
-
#
-
# It replaces references in the text with links to the appropriate items in
-
# GitLab.
-
#
-
# Supported reference formats are:
-
# * @foo for team members
-
# * for issues & pull requests:
-
# * #123
-
# * abf#123
-
# * abf/rosa-build#123
-
# * 123456 for commits
-
#
-
# It also parses Emoji codes to insert images. See
-
# http://www.emoji-cheat-sheet.com/ for a list of the supported icons.
-
#
-
# Examples
-
#
-
# >> gfm("Hey @david, can you fix this?")
-
# => "Hey <a href="/users/david">@david</a>, can you fix this?"
-
#
-
# >> gfm("Commit 35d5f7c closes #1234")
-
# => "Commit <a href="/gitlab/commits/35d5f7c">35d5f7c</a> closes <a href="/gitlab/issues/1234">#1234</a>"
-
#
-
# >> gfm(":trollface:")
-
# => "<img alt=\":trollface:\" class=\"emoji\" src=\"/images/trollface.png" title=\":trollface:\" />
-
1
module MarkdownHelper
-
1
include IssuesHelper
-
-
1
attr_reader :html_options
-
-
# Public: Parse the provided text with GitLab-Flavored Markdown
-
#
-
# text - the source text
-
# html_options - extra options for the reference links as given to link_to
-
#
-
# Note: reference links will only be generated if @project is set
-
1
def gfm(text, html_options = {})
-
return text if text.nil?
-
-
# Duplicate the string so we don't alter the original, then call to_str
-
# to cast it back to a String instead of a SafeBuffer. This is required
-
# for gsub calls to work as we need them to.
-
text = text.dup.to_str
-
-
@html_options = html_options
-
-
# Extract pre blocks so they are not altered
-
# from http://github.github.com/github-flavored-markdown/
-
text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}m) { |match| extract_piece(match) }
-
# Extract links with probably parsable hrefs
-
text.gsub!(%r{<a.*?>.*?</a>}m) { |match| extract_piece(match) }
-
# Extract images with probably parsable src
-
text.gsub!(%r{<img.*?>}m) { |match| extract_piece(match) }
-
-
# TODO: add popups with additional information
-
-
text = parse(text)
-
-
# Insert pre block extractions
-
text.gsub!(/\{gfm-extraction-(\h{32})\}/) do
-
insert_piece($1)
-
end
-
-
sanitize text.html_safe, attributes: %w(href src alt id class)
-
end
-
-
1
private
-
-
1
def extract_piece(text)
-
@extractions ||= {}
-
-
md5 = Digest::MD5.hexdigest(text)
-
@extractions[md5] = text
-
"{gfm-extraction-#{md5}}"
-
end
-
-
1
def insert_piece(id)
-
@extractions[id]
-
end
-
-
# Private: Parses text for references and emoji
-
#
-
# text - Text to parse
-
#
-
# Note: reference links will only be generated if @project is set
-
#
-
# Returns parsed text
-
1
def parse(text)
-
parse_references(text) if @project
-
parse_emoji(text)
-
end
-
-
1
REFERENCE_PATTERN = %r{
-
(?<prefix>[\W\/])? # Prefix
-
( # Reference
-
@(?<user>[a-zA-Z][a-zA-Z0-9_\-\.]*) # User/Group uname
-
|(?<issue>(?:[a-zA-Z0-9\-_]*\/)?(?:[a-zA-Z0-9\-_]*)?\#[0-9]+) # Issue ID
-
|(?<commit>[\h]{6,40}) # Commit ID
-
)
-
(?<suffix>\W)? # Suffix
-
}x.freeze
-
-
1
TYPES = [:user, :issue, :commit].freeze
-
-
1
def parse_references(text)
-
# parse reference links
-
text.gsub!(REFERENCE_PATTERN) do |match|
-
prefix = $~[:prefix]
-
suffix = $~[:suffix]
-
type = TYPES.select{|t| !$~[t].nil?}.first
-
identifier = $~[type]
-
-
# Avoid HTML entities
-
if prefix && suffix && prefix[0] == '&' && suffix[-1] == ';'
-
match
-
elsif ref_link = reference_link(type, identifier)
-
"#{prefix}#{ref_link}#{suffix}"
-
else
-
match
-
end
-
end
-
end
-
-
1
def parse_emoji(text)
-
text.gsub(/:([\w+-]+):/) do |match|
-
if emoji = Emoji.find_by_alias($1)
-
image_tag("/images/emoji/#{emoji.image_filename}", class: 'emoji', title: $1, alt: $1, size: "20x20")
-
else
-
match
-
end
-
end if text.present?
-
end
-
-
# Private: Dispatches to a dedicated processing method based on reference
-
#
-
# reference - Object reference ("@1234", "!567", etc.)
-
# identifier - Object identifier (Issue ID, SHA hash, etc.)
-
#
-
# Returns string rendered by the processing method
-
1
def reference_link(type, identifier)
-
send("reference_#{type}", identifier)
-
end
-
-
1
def reference_user(identifier)
-
member = User.where(uname: identifier).first || Group.where(uname: identifier).first
-
if member
-
link_to("@#{identifier}", "/#{identifier}", html_options.merge(title: member.fullname, class: "gfm gfm-member #{html_options[:class]}"))
-
end
-
end
-
-
1
def reference_issue(identifier)
-
if issue = Issue.find_by_hash_tag(identifier, current_user, @project)
-
if issue.pull_request
-
title = "#{PullRequest.model_name.human}: #{issue.title}"
-
url = project_pull_request_path(issue.project, issue.pull_request)
-
else
-
title = "#{Issue.model_name.human}: #{issue.title}"
-
url = project_issue_path(issue.project, issue.serial_id)
-
end
-
link_to(identifier, url, html_options.merge(title: title, class: "gfm gfm-issue #{html_options[:class]}"))
-
end
-
end
-
-
1
def reference_commit(identifier)
-
commit = @project.repo.commit(identifier) rescue nil
-
if commit
-
link_to shortest_hash_id(commit.id), commit_path(@project, commit.id)
-
title = GitPresenters::CommitAsMessagePresenter.present(commit, project: @project) do |presenter|
-
link_to(identifier, commit_path(@project, commit), html_options.merge(title: presenter.caption, class: "gfm gfm-commit #{html_options[:class]}"))
-
end
-
end
-
end
-
end
-
1
module MassBuildHelper
-
-
1
def link_to_list platform, mass_build, which
-
link_to t("layout.mass_builds.#{which}"),
-
get_list_platform_mass_build_path(platform, mass_build, kind: which, format: :txt),
-
target: "_blank" if policy(mass_build).get_list?
-
end
-
-
1
def link_to_mass_build(mass_build)
-
link_to mass_build.name, build_lists_path+"#?#{{filter: {mass_build_id: mass_build.id, ownership: 'everything'}}.to_param}"
-
end
-
-
1
def new_mass_build_data(mass_build, platform, params)
-
{
-
platform_id: mass_build.save_to_platform.try(:id),
-
repositories: platform.repositories.map do |repo|
-
{ id: repo.id,
-
name: repo.name,
-
checked: (params[:repositories]||[]).include?(repo.id.to_s) }
-
end
-
-
}.to_json
-
end
-
-
end
-
1
module PaginateHelper
-
-
1
def paginate_params
-
per_page = params[:per_page].to_i
-
per_page = 20 if per_page < 1
-
per_page = 100 if per_page >100
-
page = params[:page].to_i
-
page = nil if page == 0
-
{page: page, per_page: per_page}
-
end
-
-
1
def will_paginate(collection_or_options = nil, options = {})
-
if collection_or_options.is_a? Hash
-
options, collection_or_options = collection_or_options, nil
-
end
-
options.merge!(renderer: BootstrapLinkRenderer) unless options[:renderer]
-
options.merge!(next_label: I18n.t('datatables.next_label')) unless options[:next_label]
-
options.merge!(previous_label: I18n.t('datatables.previous_label')) unless options[:previous_label]
-
super *[collection_or_options, options].compact
-
end
-
-
1
def angularjs_paginate(options = {})
-
options.reverse_merge!(
-
{
-
per_page: params[:per_page].to_i > 0 ? params[:per_page] : 20,
-
total_items: 'total_items',
-
page: 'page',
-
select_page: "goToPage(page)"
-
}
-
)
-
-
render 'shared/angularjs_paginate', options
-
end
-
end
-
1
module PlatformsHelper
-
-
1
def platform_options
-
Platform.main.each do |p|
-
[ p.name, p.id ]
-
end
-
end
-
-
1
def platform_visibility_options
-
Platform::VISIBILITIES.map do |v|
-
[ I18n.t("activerecord.attributes.platform.visibility_types.#{v}"), v ]
-
end
-
end
-
-
1
def repository_name_postfix(platform)
-
return "" unless platform
-
return platform.released ? '/update' : '/release'
-
end
-
-
1
def platform_printed_name(platform)
-
return "" unless platform
-
platform.released? ? "#{platform.name} #{I18n.t("layout.platforms.released_suffix")}" : platform.name
-
end
-
-
1
def platform_arch_settings(platform)
-
settings = platform.platform_arch_settings
-
arches = if (arch_ids = settings.map(&:arch_id)) && arch_ids.present?
-
Arch.where('id not in (?)', arch_ids)
-
else
-
Arch.all
-
end
-
settings |= arches.map do |arch|
-
platform.platform_arch_settings.build(
-
:arch_id => arch.id,
-
:time_living => PlatformArchSetting::DEFAULT_TIME_LIVING
-
)
-
end
-
settings.sort_by{ |s| s.arch.name }
-
end
-
-
1
def fa_platform_visibility_icon(platform)
-
return nil unless platform
-
image, color = platform.hidden? ? ['lock', 'text-danger fa-fw']: ['unlock-alt', 'text-success fa-fw']
-
fa_icon(image, class: color)
-
end
-
end
-
1
module ProductBuildListsHelper
-
-
1
def product_build_list_delete_options
-
[false, true].map{ |status| [t("layout.#{status}_"), status] }
-
end
-
-
end
-
1
module ProjectsHelper
-
1
def options_for_filters(all_projects, groups, owners)
-
projects_count_by_groups = all_projects.where(owner_id: groups, owner_type: 'Group').
-
group(:owner_id).count
-
projects_count_by_owners = all_projects.where(owner_id: owners, owner_type: 'User').
-
group(:owner_id).count
-
(groups + owners).map do |o|
-
class_name = o.class.name
-
{
-
class_name: class_name.downcase,
-
id: o.id,
-
uname: o.uname,
-
count: o.is_a?(User) ? projects_count_by_owners[o.id] : projects_count_by_groups[o.id]
-
}
-
end.sort_by{ |f| f[:uname] }
-
end
-
-
1
def available_project_to_repositories(project)
-
project.project_to_repositories.includes(repository: :platform).select do |p_to_r|
-
p_to_r.repository.publish_without_qa ? true : policy(p_to_r.repository.platform).local_admin_manage?
-
end.sort_by do |p_to_r|
-
"#{p_to_r.repository.platform.name}/#{p_to_r.repository.name}"
-
end.map do |p_to_r|
-
{
-
repository_name: "#{p_to_r.repository.platform.name}/#{p_to_r.repository.name}",
-
repository_path: platform_repository_path(p_to_r.repository.platform, p_to_r.repository),
-
auto_publish: p_to_r.auto_publish?,
-
enabled: p_to_r.enabled?,
-
repository_id: p_to_r.repository_id
-
}
-
end.to_a.to_json
-
end
-
-
1
def mass_import_repositories_for_group_select
-
groups = {}
-
PlatformPolicy::Scope.new(current_user, Platform).related.order(:name).each do |platform|
-
next unless policy(platform).local_admin_manage?
-
groups[platform.name] = Repository.custom_sort(platform.repositories).map{ |r| [r.name, r.id] }
-
end
-
groups.to_a
-
end
-
-
1
def git_repo_url(name)
-
if current_user
-
"#{request.protocol}#{current_user.uname}@#{request.host_with_port}/#{name}.git"
-
else
-
"#{request.protocol}#{request.host_with_port}/#{name}.git"
-
end
-
end
-
-
1
def git_ssh_repo_url(name)
-
"git@#{request.host}:#{name}.git"
-
end
-
-
1
def options_for_collaborators_roles_select
-
Relation::ROLES.map do |role|
-
[t("layout.collaborators.role_names.#{ role }"), role]
-
end
-
end
-
-
1
def visibility_icon(visibility)
-
visibility == 'open' ? 'unlock.png' : 'lock.png'
-
end
-
-
1
def participant_class(alone_member, project)
-
c = alone_member ? 'fa-user text-primary' : 'fa-group text-primary'
-
c = 'fa-user text-success' if project.owner == current_user
-
c = 'fa-group text-success' if project.owner.in? current_user.groups
-
return c
-
end
-
-
1
def alone_member?(project)
-
Rails.cache.fetch(['ProjectsHelper#alone_member?', project, current_user]) do
-
Relation.by_target(project).by_actor(current_user).exists?
-
end
-
end
-
-
1
def participant_path(participant)
-
participant.kind_of?(User) ? user_path(participant) : group_path(participant)
-
end
-
-
1
def fa_visibility_icon(project)
-
return nil unless project
-
image, color = project.public? ? ['unlock-alt', 'text-success fa-fw'] : ['lock', 'text-danger fa-fw']
-
fa_icon(image, class: color)
-
end
-
-
1
def project_ownership_options
-
[
-
[ I18n.t('activerecord.attributes.project.who_owns.me'), 'me' ],
-
[ I18n.t('activerecord.attributes.project.who_owns.group'), 'group' ]
-
]
-
end
-
-
1
def project_visibility_options
-
Project::VISIBILITIES.map do |v|
-
[ I18n.t("activerecord.attributes.project.visibilities.#{v}"), v ]
-
end
-
end
-
-
1
def project_owner_groups_options
-
Group.can_own_project(current_user).map do |g|
-
[ g.name, g.id ]
-
end
-
end
-
end
-
1
module PullRequestHelper
-
1
def merge_activity comments, commits
-
common_comments, pull_comments = comments.partition {|c| c.automatic || c.data.blank?}
-
common_comments = common_comments.map{ |c| [c.created_at, c] }
-
pull_comments = pull_comments.group_by(&:data).map{|data, c| [c.first.created_at, [data || {}, [c].flatten]]}
-
commits = commits.map{ |c| [(c.committed_date || c.authored_date), c] }
-
(common_comments + pull_comments + commits).sort_by{ |c| c[0] }.map{ |c| c[1] }
-
end
-
-
1
def pull_status_label pull_status, options = {}
-
statuses = {'ready' => 'success', 'closed' => 'default', 'merged' => 'info', 'blocked' => 'warning'}
-
options[:class] = "#{options[:class]} label label-#{statuses[pull_status]}"
-
content_tag :span, t("projects.pull_requests.statuses.#{pull_status}"), options
-
end
-
-
1
def pull_status pull
-
if %w(blocked merged closed ready open).include? pull.status
-
t("projects.pull_requests.#{pull.status}", user: pull.issue.closer.try(:uname), to_ref: show_ref(pull, 'to'),
-
from_ref: show_ref(pull, 'from'), time: pull.issue.closed_at).html_safe
-
else
-
raise "pull id (#{pull.id}) wrong status #{pull.status} "
-
end
-
end
-
-
1
def pull_header pull
-
str = "#{t '.header'} #{t 'from'} \
-
#{show_ref pull, 'from'} \
-
#{t 'into'} \
-
#{show_ref pull, 'to'}"
-
str << " #{t 'by'} #{link_to pull.user.uname, user_path(pull.user)}" if pull.user# pull.persisted?
-
str.html_safe
-
end
-
-
#helper for helpers
-
1
def show_ref pull, which, limit = 30
-
project, ref = pull.send("#{which}_project"), pull.send("#{which}_ref")
-
fullname = if which == 'to'
-
"#{project.owner.uname.truncate limit}/#{project.name.truncate limit}"
-
elsif which == 'from'
-
"#{pull.from_project_owner_uname.truncate limit}/#{pull.from_project_name.truncate limit}"
-
end
-
link_to "#{fullname}: #{ref.truncate limit}", ref_path(project, ref), class: 'btn btn-primary'
-
end
-
-
1
def ref_path project, ref
-
if project && project.repo.branches_and_tags.map(&:name).include?(ref)
-
tree_path(project, ref)
-
else
-
'#'
-
end
-
end
-
-
1
def ref_selector_options(project, current)
-
res = []
-
value = Proc.new {|t| [t.name.truncate(50), t.name]}
-
res << [I18n.t('layout.git.repositories.branches'), project.repo.branches.map(&value).sort]
-
res << [I18n.t('layout.git.repositories.tags'), project.repo.tags.map(&value).sort]
-
-
grouped_options_for_select(res, current)
-
end
-
end
-
1
module RepositoriesHelper
-
-
end
-
1
module StatisticsHelper
-
-
1
def statistics_range_options
-
options_for_select(
-
StatisticsController::RANGES.map { |r| [I18n.t(r, scope: 'statistics.helper.period'), r] }
-
)
-
end
-
-
end
-
1
module TitleHelper
-
1
def set_page_title(title)
-
@current_page_title = title
-
end
-
1
alias_method :title, :set_page_title
-
-
1
def get_page_title(opts = {})
-
title = (@current_page_title && [@current_page_title]) || []
-
-
site_title = opts[:site].presence
-
title.unshift(site_title) if site_title
-
title = title.flatten.map(&method(:strip_tags))
-
-
title.reverse!
-
title = safe_join(title, ' - ')
-
-
title
-
end
-
end
-
1
module UsersHelper
-
-
1
def avatar_url_by_email(email, size = :small)
-
avatar_url(User.where(email: email).first || User.new(email: email), size)
-
end
-
-
1
def avatar_url(subject, size = :small)
-
if subject.try('avatar?')
-
subject.avatar.url(size)
-
elsif subject.kind_of? Group
-
'ava-big.png'
-
else
-
gravatar_url(subject.email, User::AVATAR_SIZES[size])
-
end
-
end
-
-
1
def gravatar_url(email, size = 30)
-
hex = email.present? ? Digest::MD5.hexdigest(email.try :downcase) : ''
-
"https://secure.gravatar.com/avatar/#{}?s=#{size}&r=pg"
-
end
-
end
-
1
module WikiHelper
-
-
1
def revert_path(project, first, second, name)
-
if name
-
revert_page_project_wiki_path(project, CGI.escape(name), first, second)
-
else
-
revert_project_wiki_index_path(project, first, second)
-
end
-
end
-
-
1
def compare_path(project, name)
-
if name
-
compare_project_wiki_path(@project, CGI.escape(name))
-
else
-
compare_project_wiki_index_path(@project)
-
end
-
end
-
-
1
def escaped_name
-
CGI.escape(@name)
-
end
-
-
1
def editor_path(project, name)
-
if @new
-
url_for(controller: :wiki, action: :create, project_id: project.id)
-
else
-
url_for(controller: :wiki, action: :update, project_id: project.id, id: name)
-
end
-
end
-
-
1
def view_path(project, name)
-
name == 'Home' ? project_wiki_index_path(project) : project_wiki_path(project, name)
-
end
-
-
1
def wiki_formats
-
APP_CONFIG['wiki_formats'].map do |key, val|
-
[ val, key.to_s ]
-
end.sort do |a, b|
-
a.first.downcase <=> b.first.downcase
-
end
-
end
-
-
1
def footer
-
if @footer.nil? && @page
-
@footer = !!@page.footer ? @page.footer : false
-
end
-
@footer
-
end
-
-
1
def sidebar
-
if @sidebar.nil? && @page
-
@sidebar = !!@page.sidebar ? @page.sidebar : false
-
end
-
@sidebar
-
end
-
-
1
def has_footer?
-
@footer = (@page.footer || false) if @footer.nil? && @page
-
!!@footer
-
end
-
-
1
def has_sidebar?
-
@sidebar = (@page.sidebar || false) if @sidebar.nil? && @page
-
!!@sidebar
-
end
-
-
1
def footer_content
-
has_footer? && @footer.formatted_data
-
end
-
-
1
def footer_format
-
has_footer? && @footer.format.to_s
-
end
-
-
1
def sidebar_content
-
has_sidebar? && @sidebar.formatted_data
-
end
-
-
1
def sidebar_format
-
has_sidebar? && @sidebar.format.to_s
-
end
-
-
1
def author
-
@page.version.author.name
-
end
-
-
1
def author_email
-
@page.version.author.email
-
end
-
-
1
def user_path_by_user(user)
-
(user.present?) ? user_path(user) : 'javascript:void(0)'
-
end
-
-
1
def user_link_by_user(user)
-
link_to (user.present?) ? user.uname : author, user_path_by_user(user)
-
end
-
-
1
def date
-
@page.version.authored_date
-
end
-
-
1
def format
-
@page.try(:format) || 'markdown'
-
end
-
end
-
1
module AbfWorker
-
1
class BaseObserver
-
1
COMPLETED = 0
-
1
FAILED = 1
-
1
PENDING = 2
-
1
STARTED = 3
-
1
CANCELED = 4
-
1
TESTS_FAILED = 5
-
-
1
attr_accessor :status, :options
-
-
1
def initialize(options, subject_class)
-
@status = options['status'].to_i
-
@options = options
-
@subject_class = subject_class
-
end
-
-
1
def perform
-
raise NotImplementedError, "You should implement this method"
-
end
-
-
1
protected
-
-
1
def subject
-
@subject ||= @subject_class.find(options['id'])
-
end
-
-
1
def update_results
-
now = Time.zone.now.to_i
-
results = options['results'] || []
-
results.each{ |r| r['timestamp'] = now }
-
results += subject.results || []
-
sort_results_and_save(results)
-
end
-
-
1
def sort_results_and_save(results, item = subject)
-
item.results = results.sort_by{ |r| [r['timestamp'].to_s, r['file_name'].to_s] }
-
item.save(validate: false)
-
end
-
-
end
-
end
-
1
module AbfWorker
-
1
class IsoWorkerObserver < AbfWorker::BaseObserver
-
1
@queue = :iso_worker_observer
-
-
1
def self.perform(options)
-
new(options, ProductBuildList).perform
-
end
-
-
1
def perform
-
case status
-
when COMPLETED
-
subject.build_success
-
when FAILED
-
-
case options['exit_status'].to_i
-
when ProductBuildList::BUILD_COMPLETED_PARTIALLY
-
subject.build_success_partially
-
else
-
subject.build_error
-
end
-
-
when STARTED
-
subject.start_build
-
when CANCELED
-
subject.build_canceled
-
end
-
update_results if status != STARTED
-
end
-
-
end
-
end
-
1
module AbfWorker
-
1
class PublishObserver < AbfWorker::BaseObserver
-
1
@queue = :publish_observer
-
-
1
def self.perform(options)
-
new(options, BuildList).perform
-
end
-
-
1
def perform
-
return if status == STARTED # do nothing when publication started
-
extra = options['extra']
-
repository_status = RepositoryStatus.where(id: extra['repository_status_id']).first
-
begin
-
-
if extra['regenerate'] || extra['regenerate_platform']
-
log_sha1 = (options['results'].try(:first) || {}).fetch('sha1', nil)
-
end
-
-
if extra['regenerate'] # Regenerate metadata
-
repository_status.last_regenerated_at = Time.now.utc
-
repository_status.last_regenerated_status = status
-
repository_status.last_regenerated_log_sha1 = log_sha1
-
elsif extra['regenerate_platform'] # Regenerate metadata for Software Center
-
if platform = Platform.where(id: extra['platform_id']).first
-
platform.last_regenerated_at = Time.now.utc
-
platform.last_regenerated_status = status
-
platform.last_regenerated_log_sha1 = log_sha1
-
platform.ready
-
end
-
elsif extra['create_container'] # Container has been created
-
case status
-
when COMPLETED
-
subject.published_container
-
when FAILED, CANCELED
-
subject.fail_publish_container
-
end
-
update_results
-
elsif !extra['resign'] # Simple publish
-
bls = extra['build_lists_for_cleanup_from_testing']
-
if status != COMPLETED && bls.present?
-
AbfWorkerService::Base.cleanup_packages_from_testing(
-
repository_status.platform_id,
-
repository_status.repository_id,
-
bls
-
)
-
end
-
update_rpm_builds
-
end
-
ensure
-
repository_status.ready if repository_status.present?
-
end
-
end
-
-
1
protected
-
-
1
def update_rpm_builds
-
build_lists = BuildList.where(id: options['build_list_ids'])
-
build_lists.each do |build_list|
-
update_results build_list
-
case status
-
when COMPLETED
-
if build_list.build_publish?
-
# 'update_column' - when project of build_list has been removed from repository
-
build_list.published || build_list.update_column(:status, BuildList::BUILD_PUBLISHED)
-
elsif build_list.build_publish_into_testing?
-
build_list.published_into_testing || build_list.update_column(:status, BuildList::BUILD_PUBLISHED_INTO_TESTING)
-
end
-
when FAILED, CANCELED
-
if build_list.build_publish?
-
build_list.fail_publish || build_list.update_column(:status, BuildList::FAILED_PUBLISH)
-
elsif build_list.build_publish_into_testing?
-
build_list.fail_publish_into_testing || build_list.update_column(:status, BuildList::FAILED_PUBLISH_INTO_TESTING)
-
end
-
end
-
AbfWorkerService::Base.unlock_build_list build_list
-
end
-
-
case status
-
when COMPLETED
-
AbfWorkerService::Base.cleanup_completed options['projects_for_cleanup']
-
when FAILED, CANCELED
-
AbfWorkerService::Base.cleanup_failed options['projects_for_cleanup']
-
end
-
end
-
-
1
def update_results(build_list = subject)
-
results = (build_list.results || []).
-
select{ |r| r['file_name'] !~ /^abfworker\:\:publish\-(container\-)*worker.*\.log$/ }
-
results |= options['results']
-
sort_results_and_save results, build_list
-
end
-
end
-
end
-
1
module AbfWorker
-
1
class RpmWorkerObserver < AbfWorker::BaseObserver
-
1
RESTARTED_BUILD_LISTS = 'abf-worker::rpm-worker-observer::restarted-build-lists'
-
-
# EXIT CODES:
-
# 6 - Unpermitted architecture
-
# other - Build error
-
1
EXIT_CODE_UNPERMITTED_ARCHITECTURE = 6
-
-
1
@queue = :rpm_worker_observer
-
-
1
def self.perform(options)
-
new(options, BuildList).perform
-
end
-
-
1
def perform
-
return if subject.valid? && restart_task
-
if options['feedback_from_user']
-
user = User.find options['feedback_from_user']
-
return if !user.system? && subject.builder != user
-
end
-
-
item = find_or_create_item
-
fill_container_data if status != STARTED
-
-
unless subject.valid?
-
Raven.capture_message('Invalid build list', extra: { id: subject.id, errors: subject.errors.map(&:full_message) })
-
item.update({status: BuildList::BUILD_ERROR})
-
subject.build_error(false)
-
subject.save(validate: false)
-
return
-
end
-
-
if options['hostname']
-
subject.update_attribute(:hostname, options['hostname'])
-
end
-
-
if options['fail_reason']
-
subject.update_attribute(:fail_reason, options['fail_reason'])
-
end
-
-
rerunning_tests = subject.rerunning_tests?
-
-
case status
-
when COMPLETED
-
subject.build_success
-
if subject.can_auto_publish? && subject.can_publish?
-
subject.now_publish
-
elsif subject.auto_publish_into_testing? && subject.can_publish_into_testing?
-
subject.publish_into_testing
-
end
-
when FAILED
-
-
case options['exit_status'].to_i
-
when EXIT_CODE_UNPERMITTED_ARCHITECTURE
-
subject.unpermitted_arch
-
else
-
subject.build_error
-
end
-
-
item.update({status: BuildList::BUILD_ERROR}) unless rerunning_tests
-
when STARTED
-
subject.start_build
-
when CANCELED
-
item.update({status: BuildList::BUILD_CANCELED}) unless rerunning_tests || subject.tests_failed?
-
subject.build_canceled
-
when TESTS_FAILED
-
subject.tests_failed
-
end
-
-
if !rerunning_tests && [TESTS_FAILED, COMPLETED].include?(status)
-
item.update({status: BuildList::SUCCESS})
-
subject.publish_container if subject.auto_create_container?
-
end
-
end
-
-
1
protected
-
-
1
def find_or_create_item
-
subject.items.first || subject.items.create({
-
version: subject.commit_hash,
-
name: subject.project.name,
-
status: BuildList::BUILD_STARTED,
-
level: 0
-
})
-
end
-
-
1
def restart_task
-
return false if status != FAILED
-
if Redis.current.lrem(RESTARTED_BUILD_LISTS, 0, subject.id) > 0 || (options['results'] || []).size > 1
-
return false
-
else
-
Redis.current.lpush RESTARTED_BUILD_LISTS, subject.id
-
subject.update_column(:status, BuildList::BUILD_PENDING)
-
subject.update_column(:builder_id, nil)
-
return true
-
end
-
end
-
-
1
def fill_container_data
-
(options['packages'] || []).each do |package|
-
package = subject.packages.build(package)
-
package.package_type = package['fullname'] =~ /.*\.src\.rpm$/ ? 'source' : 'binary'
-
package.project_id = subject.project_id
-
package.platform_id = subject.save_to_platform_id
-
package.save!
-
end
-
update_results
-
end
-
-
end
-
end
-
1
class AutostartBuildsDailyJob
-
1
def self.perform
-
Product.autostart_iso_builds_once_a_day
-
Project.autostart_build_lists_once_a_day
-
end
-
end
-
1
class AutostartBuildsOnceEveryTwelveHoursJob
-
1
def self.perform
-
Product.autostart_iso_builds_once_a_12_hours
-
Project.autostart_build_lists_once_a_12_hours
-
end
-
end
-
1
class AutostartBuildsWeeklyJob
-
1
def self.perform
-
Product.autostart_iso_builds_once_a_week
-
Project.autostart_build_lists_once_a_week
-
end
-
end
-
1
class AutostartRegensDailyJob
-
1
def self.perform
-
Platform.autostart_metadata_regeneration("day")
-
end
-
end
-
1
class AutostartRegensWeeklyJob
-
1
def self.perform
-
Platform.autostart_metadata_regeneration("week")
-
end
-
end
-
1
module BuildLists
-
1
class BuildCancelingDestroyJob
-
1
def self.perform
-
BuildList.for_status(BuildList::BUILD_CANCELING).for_notified_date_period(nil, 1.hours.ago).destroy_all
-
end
-
end
-
end
-
1
module BuildLists
-
1
class CleanBuildrootJob
-
1
@queue = :middle
-
-
1
FILENAME = 'buildroot.tar.gz'
-
-
1
def self.perform
-
build_lists = BuildList.where(save_buildroot: true).
-
for_status(BuildList::BUILD_ERROR).
-
where('updated_at < ?', Time.now - 4.days).
-
where('results ~ ?', "file_name: #{FILENAME}")
-
-
build_lists.find_each do |build_list|
-
buildroots = build_list.results.select do |r|
-
r['file_name'] == FILENAME
-
end
-
build_list.results -= buildroots
-
build_list.save(validate: false)
-
-
clean_file_store buildroots
-
end
-
end
-
-
1
def self.clean_file_store(buildroots)
-
buildroots.each do |r|
-
FileStoreService::File.new(sha1: r['sha1']).destroy
-
end
-
end
-
-
end
-
end
-
1
module BuildLists
-
1
class CreateContainerJob
-
1
@queue = :middle
-
-
1
def self.perform(build_list_id)
-
build_list = BuildList.find(build_list_id)
-
container = AbfWorkerService::Container.new(build_list)
-
container.create!
-
end
-
-
end
-
end
-
1
module BuildLists
-
1
class DependentPackagesJob
-
1
@queue = :middle
-
-
1
def self.perform(build_list_id, user_id, project_ids, arch_ids, options)
-
build_list = BuildList.find(build_list_id)
-
return if build_list.save_to_platform.personal?
-
user = User.find(user_id)
-
-
return unless BuildListPolicy.new(user, build_list).show?
-
-
arches = Arch.where(id: arch_ids).to_a
-
Project.where(id: project_ids).to_a.each do |project|
-
next unless ProjectPolicy.new(user, project).write?
-
-
build_for_platform = save_to_platform = build_list.build_for_platform
-
save_to_repository = save_to_platform.repositories.find{ |r| r.projects.exists?(project.id) }
-
next unless save_to_repository
-
-
project_version = project.project_version_for(save_to_platform, build_for_platform)
-
project.increase_release_tag(project_version, user, "BuildList##{build_list.id}: Increase release tag")
-
-
arches.each do |arch|
-
bl = project.build_lists.build
-
bl.arch = arch
-
bl.save_to_repository = save_to_repository
-
bl.priority = user.build_priority # User builds more priority than mass rebuild with zero priority
-
bl.project_version = project_version
-
bl.user = user
-
bl.include_repos = [build_for_platform.repositories.main.first.try(:id)].compact
-
bl.include_repos |= [save_to_repository.id]
-
%i(
-
build_for_platform_id
-
update_type
-
save_to_platform_id
-
extra_build_lists
-
extra_params
-
external_nodes
-
group_id
-
).each { |field| bl[field] = build_list[field] }
-
-
bl.auto_publish_status = options['auto_publish_status']
-
%w(
-
auto_create_container
-
include_testing_subrepository
-
use_cached_chroot
-
use_extra_tests
-
).each { |field| bl[field] = options[field] }
-
-
# debug
-
begin
-
bl.save! if BuildListPolicy.new(user, bl).create?
-
rescue ActiveRecord::RecordInvalid => invalid
-
raise 'DEBUG: ' + invalid.record.errors.map(&:full_message).join('; ')
-
end
-
end
-
end
-
end
-
-
end
-
end
-
1
class CleanApiDefenderStatisticsJob
-
1
@queue = :low
-
-
1
def self.perform
-
deadline = Date.today - 1.month
-
Redis.current.keys.select do |key|
-
next if key !~ /^throttle:/
-
# See: https://github.com/datagraph/rack-throttle/blob/master/lib/rack/throttle/daily.rb#L41
-
# Formats:
-
# 'throttle:uname:%Y-%m-%dT%H', 'throttle:uname:%Y-%m-%d'
-
# example: "throttle:uname1:2014-01-25T20", "throttle:uname1:2014-01-25"
-
date = key.gsub(/.*:/, '').gsub(/T.*/, '')
-
Redis.current.del(key) if Date.parse(date) < deadline
-
end
-
end
-
-
end
-
1
class CleanRpmBuildNodeJob
-
1
@queue = :middle
-
-
1
def self.perform
-
RpmBuildNode.all.each do |n|
-
n.delete unless n.user_id
-
end
-
end
-
-
end
-
1
class CleanTempPullRequestsJob
-
1
@queue = :low
-
-
1
def self.perform
-
path = File.join(APP_CONFIG['git_path'], 'temp_pull_requests')
-
`sh -c "cd #{path} && find -mindepth 3 -maxdepth 3 -type d -mtime +0 | xargs rm -rf && find -maxdepth 2 -type d -empty -delete"`
-
end
-
end
-
1
class ClearStaleBuildersJob
-
1
@queue = :low
-
-
1
def self.perform
-
BuildList.where("updated_at < ?", 300.seconds.ago).
-
where(status: [BuildList::BUILD_PENDING, BuildList::RERUN_TESTS]).
-
where.not(builder: nil).update_all('builder_id = NULL')
-
end
-
end
-
1
class ClearUnusedInvitesJob
-
1
@queue = :low
-
-
1
def self.perform
-
Invite.outdated.unused.destroy_all
-
end
-
end
-
1
class CreateEmptyMetadataJob < Struct.new(:class_name, :id)
-
1
@queue = :low
-
-
1
def perform
-
case class_name
-
when Platform.name
-
create_empty_metadata_for_platform
-
when Repository.name
-
create_empty_metadata_for_repository Repository.find(id)
-
end
-
end
-
-
1
def self.perform(class_name, id)
-
new(class_name, id).perform
-
end
-
-
1
private
-
-
1
def create_empty_metadata_for_platform
-
platform = Platform.main.opened.find id
-
@platforms = [platform]
-
repositories = Repository.joins(:platform).
-
where(platforms: { platform_type: Platform::TYPE_PERSONAL })
-
repositories.find_each do |r|
-
create_empty_metadata_for_repository r
-
end
-
end
-
-
1
def create_empty_metadata_for_repository(repository)
-
@platforms = [repository.platform] if repository.platform.main?
-
platforms.each do |platform|
-
arch_names.each do |arch_name|
-
%w(release updates).each do |type|
-
path = "#{ repository.platform.path }/repository/"
-
path << "#{ platform.name }/" if repository.platform.personal?
-
path << "#{ arch_name }/#{ repository.name }/#{ type }"
-
create_empty_metadata(platform, path)
-
end
-
end
-
end
-
end
-
-
1
def create_empty_metadata(platform, path)
-
case platform.distrib_type
-
when 'rhel'
-
path << '/repodata/'
-
when 'mdv'
-
path << '/media_info/'
-
when 'dnf'
-
path << '/repodata/'
-
else
-
return
-
end
-
if Dir["#{ path }/*"].empty?
-
system "mkdir -p -m 0777 #{ path }"
-
system "cp -f #{ empty_metadatas(platform) }/* #{ path }/"
-
end
-
end
-
-
1
def empty_metadatas(platform)
-
Rails.root.join('public', 'metadatas', platform.distrib_type).to_s
-
end
-
-
1
def arch_names
-
@arch_names ||= Arch.pluck(:name)
-
end
-
-
1
def platforms
-
@platforms ||= Platform.main.opened.to_a
-
end
-
-
end
-
1
class DestroyProjectFromRepositoryJob
-
-
1
def self.perform(project, repository)
-
service = AbfWorkerService::Repository.new(repository)
-
service.destroy_project!(project)
-
end
-
-
end
-
1
class PublishTaskManagerJob
-
1
@queue = :middle
-
-
1
def self.perform
-
PublishTaskManagerJob.new.perform
-
end
-
-
1
def perform
-
regenerate_metadata_for_software_center
-
resign_repositories
-
regenerate_metadata
-
AbfWorkerService::Rpm.publish!
-
end
-
-
1
protected
-
-
1
def regenerate_metadata_for_software_center
-
Platform.main.waiting_for_regeneration.each do |platform|
-
AbfWorkerService::PlatformMetadata.new(platform).regenerate!
-
end
-
end
-
-
1
def resign_repositories
-
statuses = RepositoryStatus.platform_ready.
-
for_resign.includes(repository: :platform).readonly(false)
-
-
statuses.each do |repository_status|
-
AbfWorkerService::Repository.new(repository_status.repository).resign!(repository_status)
-
end
-
end
-
-
1
def regenerate_metadata
-
statuses = RepositoryStatus.platform_ready.
-
for_regeneration.includes(repository: :platform).readonly(false)
-
-
statuses.each do |repository_status|
-
AbfWorkerService::RepositoryMetadata.new(repository_status).regenerate!
-
end
-
end
-
-
-
end
-
1
class RemoveOutdatedItemsJob
-
1
def self.perform
-
log_file = Rails.root.join("log", "remove_outdated.log").to_s
-
counter_bl = 0
-
BuildList.outdated.find_each(batch_size: 100) do |bl|
-
bl.destroy && (counter_bl += 1) if bl.id != bl.last_published.first.try(:id)
-
end
-
counter_mb = 0
-
MassBuild.outdated.find_each do |mb|
-
mb.destroy && (counter_mb += 1) if mb.build_lists.count == 0
-
end
-
User.find_each do |user|
-
user.activity_feeds.outdated.destroy_all
-
end
-
counter_pbl = ProductBuildList.outdated.count
-
ProductBuildList.outdated.destroy_all
-
File.open(log_file, "w") do |f|
-
f.puts "Build Lists deleted: #{counter_bl}"
-
f.puts "Mass Builds deleted: #{counter_mb}"
-
f.puts "Product Build Lists deleted: #{counter_pbl}"
-
end
-
end
-
end
-
1
class RestartNodesJob
-
1
@queue = :low
-
-
1
def self.perform
-
return if NodeInstruction.all_locked?
-
available_nodes = RpmBuildNode.all.map{ |n| n.user_id if n.user.try(:system?) }.compact.uniq
-
NodeInstruction.where(status: NodeInstruction::READY).
-
where.not(user_id: available_nodes).find_each(&:restart)
-
end
-
-
end
-
1
class RunExtraMassBuildsJob
-
1
@queue = :low
-
-
1
def self.perform
-
RunExtraMassBuildsJob.new.perform
-
end
-
-
1
def perform
-
MassBuild.where(status: MassBuild::BUILD_PENDING).find_each do |mb|
-
next if mb.extra_mass_builds.blank?
-
emb = MassBuild.where(status: MassBuild::SUCCESS, id: mb.extra_mass_builds).to_a
-
next if emb.size != mb.extra_mass_builds.size
-
-
next if emb.find{ |mb| not_ready?(mb) }
-
mb.build_all
-
end
-
end
-
-
1
private
-
-
# Returns true if mass build has not published packages or packages without container
-
1
def not_ready?(mb)
-
mb.build_lists.count != mb.build_lists.where(
-
'status = ? OR container_status = ?',
-
BuildList::BUILD_PUBLISHED,
-
BuildList::BUILD_PUBLISHED
-
).count
-
end
-
-
end
-
1
class UserMailer < ActionMailer::Base
-
1
helper ActivityFeedsHelper
-
1
helper CommitHelper
-
-
1
default from: "\"#{APP_CONFIG['project_name']}\" <#{APP_CONFIG['do-not-reply-email']}>"
-
1
default_url_options.merge!(protocol: 'https') if APP_CONFIG['mailer_https_url']
-
-
1
include Resque::Mailer # send email async
-
-
1
def new_user_notification(user)
-
@user = user
-
mail(
-
to: email_with_name(user, user.email),
-
subject: I18n.t("notifications.subjects.new_user_notification",
-
project_name: APP_CONFIG['project_name'])
-
) do |format|
-
format.html
-
end
-
end
-
-
1
def new_comment_notification(comment, user_id)
-
@user, @comment = User.find(user_id), comment
-
subject = @comment.issue_comment? ? subject_for_issue(@comment.commentable) :
-
I18n.t('notifications.subjects.new_commit_comment_notification')
-
mail(
-
to: email_with_name(@user, @user.email),
-
subject: subject,
-
from: email_with_name(comment.user)
-
) do |format|
-
format.html
-
end
-
end
-
-
1
def new_issue_notification(issue_id, user_id)
-
@user, @issue = User.find(user_id), Issue.find(issue_id)
-
mail(
-
to: email_with_name(@user, @user.email),
-
subject: subject_for_issue(@issue, true),
-
from: email_with_name(@issue.user)
-
) do |format|
-
format.html
-
end
-
end
-
-
1
def issue_assign_notification(issue, user)
-
@issue = issue
-
mail(
-
to: email_with_name(user, user.email),
-
subject: subject_for_issue(@issue)
-
) do |format|
-
format.html
-
end
-
end
-
-
1
def build_list_notification(build_list, user)
-
set_locale user
-
@user, @build_list = user, build_list
-
-
subject = "[№ #{build_list.id}] "
-
subject << (build_list.project ? build_list.project.name_with_owner : t("layout.projects.unexisted_project"))
-
subject << " - #{build_list.human_status} "
-
subject << I18n.t("notifications.subjects.for_arch", arch: @build_list.arch.name)
-
mail(
-
to: email_with_name(user, user.email),
-
subject: subject,
-
from: email_with_name(build_list.publisher || build_list.user)
-
) do |format|
-
format.html
-
end
-
end
-
-
1
def metadata_regeneration_notification(platform, user)
-
set_locale user
-
@user, @platform = user, platform
-
-
subject = "[#{platform.name}] "
-
subject << I18n.t("notifications.subjects.metadata_regeneration", status: I18n.t("layout.regeneration_statuses.last_regenerated_statuses.#{platform.human_regeneration_status}"))
-
mail(
-
to: email_with_name(user, user.email),
-
subject: subject,
-
from: email_with_name(platform.owner)
-
) do |format|
-
format.html
-
end
-
end
-
-
1
def git_delete_branch_notification(user, options)
-
set_locale user
-
mail(
-
to: user.email,
-
subject: I18n.t('notifications.subjects.update_code', project_name: "#{options[:project_owner]}/#{options[:project_name]}")
-
) do |format|
-
format.html { render 'git_delete_branch_notification', locals: options }
-
end
-
end
-
-
1
def git_new_push_notification(user, options)
-
set_locale user
-
mail(
-
to: user.email,
-
subject: I18n.t('notifications.subjects.update_code', project_name: "#{options[:project_owner]}/#{options[:project_name]}")
-
) do |format|
-
format.html { render 'git_new_push_notification', locals: options }
-
end
-
end
-
-
1
protected
-
-
1
def set_locale(user)
-
I18n.locale = user.language if user.language
-
end
-
-
1
def email_with_name(user, email = APP_CONFIG['do-not-reply-email'])
-
"\"#{user.user_appeal}\" <#{email}>"
-
end
-
-
1
def subject_for_issue(issue, new_issue = false)
-
subject = new_issue ? '' : 'Re: '
-
subject << "[#{issue.project.name}] #{issue.title} (##{issue.serial_id})"
-
end
-
end
-
1
class ActivityFeed < ActiveRecord::Base
-
-
1
CODE = %w(git_delete_branch_notification git_new_push_notification new_comment_commit_notification)
-
1
TRACKER = %w(issue_assign_notification new_comment_notification new_issue_notification)
-
1
BUILD = %w(build_list_notification)
-
1
WIKI = %w(wiki_new_commit_notification)
-
-
1
belongs_to :user
-
1
belongs_to :creator, class_name: 'User', optional: true
-
1
serialize :data
-
-
61
default_scope { order created_at: :desc }
-
1
scope :outdated, -> { offset(1000) }
-
1
scope :by_project_name, ->(name) { where(project_name: name) if name.present? }
-
1
scope :by_owner_uname, ->(owner) { where(project_owner: owner) if owner.present? }
-
-
1
self.per_page = 20
-
-
1
def partial
-
"home/partials/#{self.kind}"
-
end
-
end
-
1
class Advisory < ActiveRecord::Base
-
1
self.include_root_in_json = false
-
1
self.per_page = 30
-
-
1
has_and_belongs_to_many :platforms
-
1
has_and_belongs_to_many :projects
-
1
has_many :build_lists
-
-
1
validates :description, :update_type, presence: true
-
1
validates :update_type, inclusion: BuildList::RELEASE_UPDATE_TYPES
-
-
1
after_create :generate_advisory_id
-
1
before_save :normalize_references, if: :references_changed?
-
-
1
ID_TEMPLATE = 'ROSA-%<type>s-%<year>d:%<id>04d'
-
1
ID_STRING_TEMPLATE = 'ROSA-%<type>s-%<year>04s:%<id>04s'
-
1
TYPES = {'security' => 'SA', 'bugfix' => 'A'}
-
-
1
scope :search_like, ->(q) {
-
q = q.to_s.strip
-
where("#{table_name}.advisory_id ILIKE :q OR #{table_name}.description ILIKE :q OR build_list_packages.fullname ILIKE :q", q: "%#{q}%").
-
joins(build_lists: :packages) if q.present?
-
}
-
1
scope :search_by_id, ->(aid) { where("#{table_name}.advisory_id ILIKE ?", "%#{aid.to_s.strip}%") }
-
1
scope :by_update_type, ->(ut) { where(update_type: ut) }
-
1
default_scope { order(created_at: :desc) }
-
-
1
def to_param
-
advisory_id
-
end
-
-
1
def attach_build_list(build_list)
-
return false if update_type != build_list.update_type
-
self.platforms << build_list.save_to_platform unless platforms.include? build_list.save_to_platform
-
self.projects << build_list.project unless projects.include? build_list.project
-
build_list.advisory = self
-
save && build_list.save
-
end
-
-
# this method fetches and structurize packages attached to current advisory.
-
1
def fetch_packages_info
-
packages_info = Hash.new { |h, k| h[k] = {} } # maaagic, it's maaagic ;)
-
build_lists.includes(:save_to_platform, :packages, :project).find_in_batches do |batch|
-
batch.each do |build_list|
-
tmp = build_list.packages.inject({srpm: nil, rpm: []}) do |h, p|
-
p.package_type == 'binary' ? h[:rpm] << p.fullname : h[:srpm] = p.fullname
-
h
-
end
-
h = { build_list.project => tmp }
-
packages_info[build_list.save_to_platform].merge!(h) do |pr, old, new|
-
{srpm: new[:srpm], rpm: old[:rpm].concat(new[:rpm]).uniq}
-
end
-
end
-
end
-
packages_info
-
end
-
-
1
protected
-
-
1
def generate_advisory_id
-
self.advisory_id = sprintf(ID_TEMPLATE, type: TYPES[self.update_type], year: Time.now.utc.year, id: self.id)
-
self.save
-
end
-
-
1
def normalize_references
-
self.references.gsub!(/\r| /, '')
-
self.references = self.references.split('\n').map do |ref|
-
ref = CGI::escapeHTML(ref)
-
ref = "http://#{ref}" unless ref =~ %r[^http(s?)://*]
-
ref
-
end.join("\n")
-
end
-
-
end
-
1
class Arch < ActiveRecord::Base
-
1
DEFAULT = %w[i586 x86_64]
-
-
1
has_many :build_lists, dependent: :destroy
-
-
1
validates :name, presence: true, uniqueness: true
-
-
1
scope :recent, -> { order(:name) }
-
end
-
1
class Avatar < ActiveRecord::Base
-
1
self.abstract_class = true
-
-
1
MAX_AVATAR_SIZE = 5.megabyte
-
1
AVATAR_SIZES = { micro: 16, small: 30, medium: 40, big: 81 }
-
-
1
AVATAR_SIZES_HASH = {}.tap do |styles|
-
1
AVATAR_SIZES.each do |name, size|
-
4
styles[name] = { geometry: "#{size}x#{size}#", format: :jpg,
-
convert_options: '-strip -background white -flatten -quality 70' }
-
end
-
end
-
-
1
has_attached_file :avatar, styles: AVATAR_SIZES_HASH
-
1
validates_attachment_size :avatar, less_than_or_equal_to: MAX_AVATAR_SIZE
-
1
validates_attachment_content_type :avatar, content_type: /\Aimage/
-
1
validates_attachment_file_name :avatar, matches: [ /(png|jpe?g|gif|bmp|tif?f)\z/i ]
-
end
-
1
class BuildList < ActiveRecord::Base
-
1
include CommitAndVersion
-
1
include FileStoreClean
-
1
include AbfWorkerMethods
-
1
include Feed::BuildList
-
1
include BuildListObserver
-
1
include EventLoggable
-
1
include ExternalNodable
-
-
1
self.per_page = 25
-
-
1
belongs_to :project
-
1
belongs_to :arch
-
1
belongs_to :save_to_platform, class_name: 'Platform'
-
1
belongs_to :save_to_repository, class_name: 'Repository'
-
1
belongs_to :build_for_platform, class_name: 'Platform'
-
1
belongs_to :user
-
1
belongs_to :builder, class_name: 'User', optional: true
-
1
belongs_to :publisher, class_name: 'User', optional: true
-
1
belongs_to :advisory, optional: true
-
1
belongs_to :mass_build, counter_cache: true, optional: true
-
1
has_many :items, class_name: '::BuildList::Item', dependent: :destroy
-
1
has_many :packages, class_name: '::BuildList::Package', dependent: :destroy
-
1
has_many :source_packages, -> { where(package_type: 'source') }, class_name: '::BuildList::Package'
-
-
UPDATE_TYPES = [
-
1
UPDATE_TYPE_BUGFIX = 'bugfix',
-
UPDATE_TYPE_SECURITY = 'security',
-
UPDATE_TYPE_ENHANCEMENT = 'enhancement',
-
UPDATE_TYPE_RECOMMENDED = 'recommended',
-
UPDATE_TYPE_NEWPACKAGE = 'newpackage'
-
]
-
-
1
RELEASE_UPDATE_TYPES = [UPDATE_TYPE_BUGFIX, UPDATE_TYPE_SECURITY]
-
1
EXTRA_PARAMS = %w[cfg_options cfg_urpm_options build_src_rpm build_rpm]
-
-
AUTO_PUBLISH_STATUSES = [
-
1
AUTO_PUBLISH_STATUS_NONE = 'none',
-
AUTO_PUBLISH_STATUS_DEFAULT = 'default',
-
AUTO_PUBLISH_STATUS_TESTING = 'testing'
-
]
-
-
1
validates :project, :project_id,
-
:project_version,
-
:arch, :arch_id,
-
:include_repos,
-
:build_for_platform, :build_for_platform_id,
-
:save_to_platform, :save_to_platform_id,
-
:save_to_repository, :save_to_repository_id,
-
presence: true
-
-
1
validates_numericality_of :priority, greater_than_or_equal_to: 0
-
1
validates :auto_publish_status, inclusion: { in: AUTO_PUBLISH_STATUSES }
-
1
validates :update_type, inclusion: UPDATE_TYPES,
-
6
unless: Proc.new { |b| b.advisory.present? }
-
1
validates :update_type, inclusion: { in: RELEASE_UPDATE_TYPES, message: I18n.t('flash.build_list.frozen_platform') },
-
6
if: Proc.new { |b| b.advisory.present? }
-
1
validate -> {
-
6
if save_to_platform.try(:main?) && save_to_platform_id != build_for_platform_id
-
errors.add(:build_for_platform, I18n.t('flash.build_list.wrong_platform'))
-
end
-
}
-
1
validate -> {
-
6
unless build_for_platform.try :main?
-
errors.add(:build_for_platform, I18n.t('flash.build_list.wrong_build_for_platform'))
-
end
-
}
-
1
validate -> {
-
6
if save_to_repository.try(:platform_id) != save_to_platform.try(:id)
-
errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_repository'))
-
end
-
}
-
1
validate -> {
-
6
if build_for_platform && build_for_platform.repositories.where(id: include_repos).count != include_repos.try(:size)
-
errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_include_repos'))
-
end
-
}
-
1
validate -> {
-
6
unless save_to_repository && save_to_repository.projects.exists?(project_id)
-
errors.add(:save_to_repository, I18n.t('flash.build_list.wrong_project'))
-
end
-
}
-
1
before_validation -> {
-
3
self.include_repos = ([] << include_repos).flatten.uniq if include_repos.present?
-
}, on: :create
-
1
before_validation :prepare_extra_repositories, on: :create
-
1
before_validation :prepare_extra_build_lists, on: :create
-
1
before_validation :prepare_extra_params, on: :create
-
1
before_validation :prepare_auto_publish_status, on: :create
-
-
1
LIVE_TIME = 4.week # for unpublished
-
1
MAX_LIVE_TIME = 3.month # for published
-
1
STATUSES, HUMAN_STATUSES = [], {}
-
[
-
1
%w(SUCCESS 0),
-
# %w(ERROR 1),
-
# %w(PROJECT_SOURCE_ERROR 6),
-
# %w(DEPENDENCIES_ERROR 555),
-
%w(BUILD_ERROR 666),
-
%w(PACKAGES_FAIL 777),
-
%w(BUILD_STARTED 3000),
-
%w(BUILD_CANCELED 5000),
-
%w(WAITING_FOR_RESPONSE 4000),
-
%w(BUILD_PENDING 2000),
-
%w(RERUN_TESTS 2500),
-
%w(RERUNNING_TESTS 2550),
-
%w(BUILD_PUBLISHED 6000),
-
%w(BUILD_PUBLISH 7000),
-
%w(FAILED_PUBLISH 8000),
-
%w(REJECTED_PUBLISH 9000),
-
%w(BUILD_CANCELING 10000),
-
%w(TESTS_FAILED 11000),
-
%w(BUILD_PUBLISHED_INTO_TESTING 12000),
-
%w(BUILD_PUBLISH_INTO_TESTING 13000),
-
%w(FAILED_PUBLISH_INTO_TESTING 14000),
-
%w(UNPERMITTED_ARCH 15000)
-
].each do |kind, value|
-
19
value = value.to_i
-
19
const_set kind, value
-
19
STATUSES << value
-
19
HUMAN_STATUSES[value] = kind.downcase.to_sym
-
end
-
1
STATUSES.freeze
-
1
HUMAN_STATUSES.freeze
-
-
4
scope :recent, -> { order(updated_at: :desc) }
-
1
scope :for_extra_build_lists, ->(ids, save_to_platform) {
-
s = where(id: ids, container_status: BuildList::BUILD_PUBLISHED)
-
s = s.where(save_to_platform_id: save_to_platform.id) if save_to_platform && save_to_platform.main?
-
s
-
}
-
4
scope :for_status, ->(status) { where(status: status) if status.present? }
-
1
scope :for_user, ->(user) { where(user_id: user.id) }
-
1
scope :not_owned_external_nodes, -> { where("#{table_name}.external_nodes is null OR #{table_name}.external_nodes != ?", :owned) }
-
1
scope :external_nodes, ->(type) { where("#{table_name}.external_nodes = ?", type) }
-
1
scope :oldest, -> { where("#{table_name}.updated_at < ?", Time.zone.now - 15.seconds) }
-
4
scope :for_platform, ->(platform) { where(build_for_platform_id: platform) if platform.present? }
-
1
scope :by_mass_build, ->(mass_build) { where(mass_build_id: mass_build) }
-
4
scope :scoped_to_arch, ->(arch) { where(arch_id: arch) if arch.present? }
-
1
scope :scoped_to_save_platform, ->(pl_id) { where(save_to_platform_id: pl_id) if pl_id.present? }
-
1
scope :scoped_to_build_for_platform, ->(pl_id) { where(build_for_platform_id: pl_id) if pl_id.present? }
-
1
scope :scoped_to_save_to_repository, ->(repo_id) { where(save_to_repository_id: repo_id) if repo_id.present? }
-
1
scope :scoped_to_project_version, ->(pr_version) { where(project_version: pr_version) if pr_version.present? }
-
1
scope :scoped_to_is_circle, ->(is_circle) { where(is_circle: is_circle) }
-
1
scope :for_creation_date_period, ->(start_date, end_date) {
-
s = all
-
s = s.where(["#{table_name}.created_at >= ?", start_date]) if start_date
-
s = s.where(["#{table_name}.created_at <= ?", end_date]) if end_date
-
s
-
}
-
1
scope :for_notified_date_period, ->(start_date, end_date) {
-
s = all
-
s = s.where("#{table_name}.updated_at >= ?", start_date) if start_date.present?
-
s = s.where("#{table_name}.updated_at <= ?", end_date) if end_date.present?
-
s
-
}
-
1
scope :scoped_to_project_name, ->(project_name) {
-
joins(:project).where('projects.name LIKE ?', "%#{project_name}%") if project_name.present?
-
}
-
1
scope :scoped_to_new_core, ->(new_core) { where(new_core: new_core) }
-
1
scope :outdated, -> (now = Time.now) {
-
where(<<-SQL, now - LIVE_TIME, [BUILD_PUBLISHED,BUILD_PUBLISHED_INTO_TESTING], now - MAX_LIVE_TIME)
-
(
-
#{table_name}.created_at < ? AND
-
#{table_name}.status NOT IN (?) AND
-
#{table_name}.mass_build_id IS NULL
-
) OR (
-
#{table_name}.created_at < ?
-
)
-
SQL
-
}
-
1
scope :published_container, -> { where(container_status: BUILD_PUBLISHED) }
-
-
1
serialize :additional_repos
-
1
serialize :include_repos
-
1
serialize :results, Array
-
1
serialize :extra_repositories, Array
-
1
serialize :extra_build_lists, Array
-
1
serialize :extra_params, Hash
-
-
1
after_create :place_build
-
1
after_destroy :remove_container
-
-
1
state_machine :status, initial: :waiting_for_response do
-
1
after_transition on: :published,
-
do: %i(set_version_and_tag actualize_packages)
-
1
after_transition on: :publish, do: :set_publisher
-
1
after_transition(on: :publish) do |build_list, transition|
-
if transition.from == BUILD_PUBLISHED_INTO_TESTING
-
build_list.cleanup_packages_from_testing
-
end
-
end
-
1
after_transition on: :cancel, do: :cancel_job
-
-
1
after_transition on: %i(published fail_publish build_error tests_failed unpermitted_arch), do: :notify_users
-
1
after_transition on: :build_success, do: :notify_users,
-
unless: ->(build_list) { build_list.auto_publish? || build_list.auto_publish_into_testing? }
-
-
1
event :place_build do
-
1
transition waiting_for_response: :build_pending
-
end
-
-
1
event :unpermitted_arch do
-
1
transition [:build_started, :build_canceling, :build_canceled] => :unpermitted_arch
-
end
-
-
1
event :rerun_tests do
-
1
transition %i(success tests_failed) => :rerun_tests
-
end
-
-
1
event :start_build do
-
1
transition build_pending: :build_started
-
1
transition rerun_tests: :rerunning_tests
-
end
-
-
1
event :cancel do
-
1
transition [:build_pending, :build_started] => :build_canceling
-
1
transition [:rerun_tests, :rerunning_tests] => :tests_failed
-
end
-
-
# build_canceling: :build_canceled - canceling from UI
-
# build_started: :build_canceled - canceling from worker by time-out (time_living has been expired)
-
1
event :build_canceled do
-
1
transition [:build_canceling, :build_started, :build_pending] => :build_canceled
-
1
transition [:rerun_tests, :rerunning_tests] => :tests_failed
-
end
-
-
1
event :published do
-
1
transition [:build_publish, :rejected_publish] => :build_published
-
end
-
-
1
event :fail_publish do
-
1
transition [:build_publish, :rejected_publish] => :failed_publish
-
end
-
-
1
event :publish do
-
1
transition [
-
:success,
-
:failed_publish,
-
:build_published,
-
:tests_failed,
-
:failed_publish_into_testing,
-
:build_published_into_testing
-
] => :build_publish
-
1
transition [:success, :failed_publish, :failed_publish_into_testing] => :failed_publish
-
end
-
-
1
event :reject_publish do
-
1
transition [
-
:success,
-
:failed_publish,
-
:tests_failed,
-
:failed_publish_into_testing,
-
:build_published_into_testing
-
] => :rejected_publish
-
end
-
-
# ===== into testing - start
-
-
1
event :published_into_testing do
-
1
transition [:build_publish_into_testing, :rejected_publish] => :build_published_into_testing
-
end
-
-
1
event :fail_publish_into_testing do
-
1
transition [:build_publish_into_testing, :rejected_publish] => :failed_publish_into_testing
-
end
-
-
1
event :publish_into_testing do
-
1
transition [
-
:success,
-
:failed_publish,
-
:tests_failed,
-
:failed_publish_into_testing,
-
:build_published_into_testing
-
] => :build_publish_into_testing
-
1
transition [:success, :failed_publish, :failed_publish_into_testing] => :failed_publish_into_testing
-
end
-
-
# ===== into testing - end
-
-
1
event :build_success do
-
1
transition [:build_started, :build_canceling, :build_canceled, :rerunning_tests, :build_pending] => :success
-
end
-
-
1
[:build_error, :tests_failed].each do |kind|
-
2
event kind do
-
2
transition [:build_started, :build_canceling, :build_canceled, :build_pending] => kind
-
2
transition rerunning_tests: :tests_failed
-
end
-
end
-
-
1
HUMAN_STATUSES.each do |code,name|
-
19
state name, value: code
-
end
-
end
-
-
1
later :publish, queue: :middle
-
-
1
HUMAN_CONTAINER_STATUSES = { WAITING_FOR_RESPONSE => :waiting_for_publish,
-
BUILD_PUBLISHED => :container_published,
-
BUILD_PUBLISH => :container_publish,
-
FAILED_PUBLISH => :container_failed_publish
-
}.freeze
-
-
1
state_machine :container_status, initial: :waiting_for_publish do
-
-
1
after_transition on: :publish_container, do: :create_container
-
1
after_transition on: [:fail_publish_container, :destroy_container],
-
do: :remove_container
-
-
1
event :publish_container do
-
1
transition [:waiting_for_publish, :container_failed_publish] => :container_publish,
-
if: :can_create_container?
-
end
-
-
1
event :published_container do
-
1
transition container_publish: :container_published
-
end
-
-
1
event :fail_publish_container do
-
1
transition container_publish: :container_failed_publish
-
end
-
-
1
event :destroy_container do
-
1
transition [:container_failed_publish, :container_published, :waiting_for_publish] => :waiting_for_publish
-
end
-
-
1
HUMAN_CONTAINER_STATUSES.each do |code,name|
-
4
state name, value: code
-
end
-
end
-
-
1
def set_version_and_tag
-
pkg = self.packages.where(package_type: 'source', project_id: self.project_id).first
-
# TODO: remove 'return' after deployment ABF kernel 2.0
-
return if pkg.nil? # For old client that does not sends data about packages
-
self.package_version = "#{pkg.platform.name}-#{pkg.version}-#{pkg.release}"
-
system("cd #{self.project.repo.path} && git tag #{self.package_version} #{self.commit_hash}") # TODO REDO through grit
-
save
-
end
-
-
1
def actualize_packages
-
ActiveRecord::Base.transaction do
-
# packages from previous build_list
-
self.last_published.limit(2).last.packages.update_all actual: false
-
self.packages.update_all actual: true
-
end
-
end
-
-
1
def can_create_container?
-
[SUCCESS, BUILD_PUBLISH, FAILED_PUBLISH, BUILD_PUBLISHED, TESTS_FAILED, BUILD_PUBLISHED_INTO_TESTING, FAILED_PUBLISH_INTO_TESTING].include?(status) && [WAITING_FOR_RESPONSE, FAILED_PUBLISH].include?(container_status)
-
end
-
-
1
def can_publish_into_repository?
-
return true if !save_to_repository.synchronizing_publications? || save_to_platform.personal? || project.architecture_dependent?
-
arch_ids = save_to_platform.platform_arch_settings.by_default.pluck(:arch_id)
-
BuildList.where(
-
project_id: project_id,
-
save_to_repository_id: save_to_repository_id,
-
arch_id: arch_ids,
-
commit_hash: commit_hash,
-
status: [
-
SUCCESS,
-
BUILD_PUBLISHED,
-
BUILD_PUBLISH,
-
FAILED_PUBLISH,
-
TESTS_FAILED,
-
BUILD_PUBLISHED_INTO_TESTING,
-
BUILD_PUBLISH_INTO_TESTING,
-
FAILED_PUBLISH_INTO_TESTING
-
]
-
).group(:arch_id).count == arch_ids.size
-
end
-
-
#TODO: Share this checking on product owner.
-
1
def can_cancel?
-
build_started? || build_pending?
-
end
-
-
# Comparison between versions of current and last published build_list
-
# @return [Boolean]
-
# - false if no new packages
-
# - false if version of packages is less than version of pubished packages.
-
# - true if version of packages is equal to version of pubished packages (only if platform is not released or platform is RHEL).
-
# - true if version of packages is greater than version of pubished packages.
-
1
def has_new_packages?
-
if last_bl = last_published.joins(:source_packages).where(build_list_packages: {actual: true}).last
-
source_packages.each do |nsp|
-
sp = last_bl.source_packages.find{ |sp| nsp.name == sp.name }
-
return true unless sp
-
comparison = nsp.rpmvercmp(sp)
-
return true if comparison == 1
-
return comparison == 0 && ( !save_to_platform.released? || save_to_platform.distrib_type == 'rhel' )
-
end
-
else
-
return true # no published packages
-
end
-
return false # no new packages
-
end
-
-
1
def auto_publish?
-
6
auto_publish_status == AUTO_PUBLISH_STATUS_DEFAULT
-
end
-
-
1
def auto_publish_into_testing?
-
auto_publish_status == AUTO_PUBLISH_STATUS_TESTING
-
end
-
-
# TODO: remove later
-
1
def auto_publish=(value)
-
self.auto_publish_status = value.present? ? AUTO_PUBLISH_STATUS_DEFAULT : AUTO_PUBLISH_STATUS_NONE
-
end
-
-
1
def can_auto_publish?
-
auto_publish? && can_publish? && has_new_packages? && can_publish_into_repository?
-
end
-
-
1
def can_publish?
-
super &&
-
valid_branch_for_publish? &&
-
extra_build_lists_published? &&
-
save_to_repository.projects.exists?(id: project_id)
-
end
-
-
1
def can_publish_into_testing?
-
super && valid_branch_for_publish?
-
end
-
-
1
def extra_build_lists_published?
-
# All extra build lists should be published before publishing this build list for main platforms!
-
return true unless save_to_platform.main?
-
BuildList.where(id: extra_build_lists).where('status != ?', BUILD_PUBLISHED).count == 0
-
end
-
-
1
def human_average_build_time
-
I18n.t('layout.project_statistics.human_average_build_time', {hours: (average_build_time/3600).to_i, minutes: (average_build_time%3600/60).to_i})
-
end
-
-
1
def formatted_average_build_time
-
"%02d:%02d" % [average_build_time / 3600, average_build_time % 3600 / 60]
-
end
-
-
1
def average_build_time
-
return 0 unless project
-
@average_build_time ||= project.project_statistics.
-
find{ |ps| ps.arch_id == arch_id }.try(:average_build_time) || 0
-
end
-
-
1
def self.human_status(status)
-
I18n.t("layout.build_lists.statuses.#{HUMAN_STATUSES[status]}")
-
end
-
-
1
def human_status
-
self.class.human_status(status)
-
end
-
-
1
def self.status_by_human(human)
-
HUMAN_STATUSES.key human
-
end
-
-
1
def set_items(items_hash)
-
self.items = []
-
-
items_hash.each do |level, items|
-
items.each do |item|
-
self.items << self.items.build(name: item['name'], version: item['version'], level: level.to_i)
-
end
-
end
-
end
-
-
1
def set_packages(pkg_hash, project_name)
-
prj = Project.joins(repositories: :platform).where('platforms.id = ?', save_to_platform.id).find_by!(name: project_name)
-
build_package(pkg_hash['srpm'], 'source', prj) {|p| p.save!}
-
pkg_hash['rpm'].each do |rpm_hash|
-
build_package(rpm_hash, 'binary', prj) {|p| p.save!}
-
end
-
end
-
-
1
def event_log_message
-
{project: project.name, version: project_version, arch: arch.name}.inspect
-
end
-
-
1
def current_duration
-
if started_at
-
(Time.now.utc - started_at.utc).to_i
-
else
-
0
-
end
-
end
-
-
1
def human_current_duration
-
I18n.t("layout.build_lists.human_current_duration", {hours: (current_duration/3600).to_i, minutes: (current_duration%3600/60).to_i})
-
end
-
-
1
def human_duration
-
I18n.t("layout.build_lists.human_duration", {hours: (duration.to_i/3600).to_i, minutes: (duration.to_i%3600/60).to_i})
-
end
-
-
1
def in_work?
-
status == BUILD_STARTED
-
#[WAITING_FOR_RESPONSE, BUILD_PENDING, BUILD_STARTED].include?(status)
-
end
-
-
1
def associate_and_create_advisory(params)
-
build_advisory(params){ |a| a.update_type = update_type }
-
advisory.attach_build_list(self)
-
end
-
-
1
def can_attach_to_advisory?
-
!save_to_repository.publish_without_qa &&
-
save_to_platform.main? &&
-
save_to_platform.released &&
-
build_published?
-
end
-
-
1
def log(load_lines=nil)
-
if new_core?
-
worker_log = abf_worker_log
-
Pygments.highlight(worker_log, lexer: 'sh') rescue worker_log
-
else
-
I18n.t('layout.build_lists.log.not_available')
-
end
-
end
-
-
1
def last_published(testing = false)
-
3
BuildList.where(project_id: self.project_id,
-
save_to_repository_id: self.save_to_repository_id)
-
.for_platform(self.build_for_platform_id)
-
.scoped_to_arch(self.arch_id)
-
3
.for_status(testing ? BUILD_PUBLISHED_INTO_TESTING : BUILD_PUBLISHED)
-
.recent
-
end
-
-
1
def sha1_of_file_store_files
-
packages.pluck(:sha1).compact | (results || []).map{ |r| r['sha1'] }.compact
-
end
-
-
1
def cancel_job
-
if [BUILD_PENDING, RERUN_TESTS].include?(status)
-
build_canceled
-
elsif
-
send_stop_signal
-
end
-
true
-
end
-
-
1
def abf_worker_args
-
repos = include_repos
-
include_repos_hash = {}.tap do |h|
-
Repository.where(id: (repos | (extra_repositories || [])) ).each do |repo|
-
path, prefix = repo.platform.public_downloads_url(
-
repo.platform.main? ? nil : build_for_platform.name,
-
arch.name,
-
repo.name
-
), "#{repo.platform.name}_#{repo.name}_"
-
h["#{prefix}release"] = insert_token_to_path(path + 'release', repo.platform)
-
h["#{prefix}updates"] = insert_token_to_path(path + 'updates', repo.platform) if repo.platform.main?
-
h["#{prefix}testing"] = insert_token_to_path(path + 'testing', repo.platform) if include_testing_subrepository?
-
end
-
end
-
host = EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host]
-
BuildList.where(id: extra_build_lists).each do |bl|
-
path = "#{APP_CONFIG['downloads_url']}/#{bl.save_to_platform.name}/container/"
-
path << "#{bl.id}/#{bl.arch.name}/#{bl.save_to_repository.name}/release"
-
include_repos_hash["container_#{bl.id}"] = insert_token_to_path(path, bl.save_to_platform)
-
end
-
-
git_project_address = project.git_project_address user
-
# git_project_address.gsub!(/^http:\/\/(0\.0\.0\.0|localhost)\:[\d]+/, 'https://abf.rosalinux.ru') unless Rails.env.production?
-
-
-
cmd_params = {
-
'PACKAGE' => project.name,
-
'GIT_PROJECT_ADDRESS' => git_project_address,
-
'GIT_REPO' => git_project_address,
-
'COMMIT_HASH' => commit_hash,
-
'PROJECT_VERSION' => project_version,
-
'USE_EXTRA_TESTS' => use_extra_tests?,
-
'SAVE_BUILDROOT' => save_buildroot?,
-
'EXTRA_CFG_OPTIONS' => extra_params['cfg_options'],
-
'EXTRA_CFG_URPM_OPTIONS' => extra_params['cfg_urpm_options'],
-
'EXTRA_BUILD_SRC_RPM_OPTIONS' => extra_params['build_src_rpm'],
-
'EXTRA_BUILD_RPM_OPTIONS' => extra_params['build_rpm'],
-
'PLATFORM_NAME' => build_for_platform.name,
-
'FILE_STORE_ADDR' => APP_CONFIG['file_store_url'].gsub(/\/$/, '')
-
}
-
cmd_params.merge!(
-
'RERUN_TESTS' => true,
-
'PACKAGES' => packages.pluck(:sha1).compact * ' '
-
) if rerun_tests?
-
if use_cached_chroot?
-
sha1 = build_for_platform.cached_chroot(arch.name)
-
cmd_params.merge!('CACHED_CHROOT_SHA1' => sha1) if sha1.present?
-
end
-
# cmd_params = cmd_params.map{ |k, v| "#{k}='#{v}'" }.join(' ')
-
-
{
-
id: id,
-
time_living: (build_for_platform.platform_arch_settings.by_arch(arch).first.try(:time_living) || PlatformArchSetting::DEFAULT_TIME_LIVING),
-
distrib_type: build_for_platform.distrib_type,
-
cmd_params: cmd_params,
-
include_repos: include_repos_hash,
-
platform: {
-
type: build_for_platform.distrib_type,
-
name: build_for_platform.name,
-
arch: arch.name
-
},
-
rerun_tests: rerun_tests?,
-
user: { uname: user.uname, email: user.email }
-
}
-
end
-
-
1
def cleanup_packages_from_testing
-
AbfWorkerService::Base.cleanup_packages_from_testing(
-
build_for_platform_id,
-
save_to_repository_id,
-
id
-
)
-
end
-
-
1
def valid_branch_for_publish?
-
@valid_branch_for_publish ||= begin
-
save_to_platform.personal? ||
-
save_to_repository.publish_builds_only_from_branch.blank? ||
-
( project_version == save_to_repository.publish_builds_only_from_branch ) ||
-
project.repo.git.native(:branch, {}, '--contains', commit_hash).
-
gsub(/\*/, '').split(/\n/).map(&:strip).
-
include?(save_to_repository.publish_builds_only_from_branch)
-
end
-
end
-
-
1
protected
-
-
1
def create_container
-
Resque.enqueue(BuildLists::CreateContainerJob, id)
-
end
-
-
1
def remove_container
-
AbfWorkerService::Container.new(self).destroy! if save_to_platform
-
end
-
-
1
def abf_worker_priority
-
mass_build_id ? '' : 'default'
-
end
-
-
1
def abf_worker_base_queue
-
'rpm_worker'
-
end
-
-
1
def insert_token_to_path(path, platform)
-
if platform.hidden?
-
path.gsub(/^http:\/\//, "http://#{user.authentication_token}:@")
-
else
-
path
-
end
-
end
-
-
1
def notify_users
-
unless mass_build_id
-
users = [user, publisher].compact.uniq.select{ |u| u.notifier.can_notify? && u.notifier.new_build? }
-
-
# find associated users
-
users |= project.all_members(:notifier).select do |u|
-
u.notifier.can_notify? && u.notifier.new_associated_build?
-
end if project
-
users.each{ |u| UserMailer.build_list_notification(self, u).deliver }
-
end
-
end # notify_users
-
-
1
def build_package(pkg_hash, package_type, prj)
-
packages.create(pkg_hash) do |p|
-
p.project = prj
-
p.platform = save_to_platform
-
p.package_type = package_type
-
yield p
-
end
-
end
-
-
1
def set_publisher
-
self.publisher ||= user
-
save
-
end
-
-
1
def prepare_extra_repositories
-
3
if save_to_platform && save_to_platform.main?
-
3
self.extra_repositories = nil
-
else
-
self.extra_repositories = PlatformPolicy::Scope.new(user, Repository.joins(:platform)).show.
-
where(id: extra_repositories).
-
pluck('repositories.id')
-
end
-
end
-
-
1
def prepare_extra_build_lists
-
3
if mass_build && mass_build.extra_mass_builds.present?
-
extra_build_lists << BuildList.where(mass_build_id: mass_build.extra_mass_builds).pluck(:id)
-
extra_build_lists.flatten!
-
end
-
3
return if extra_build_lists.blank?
-
bls = BuildListPolicy::Scope.new(user, BuildList).read.
-
for_extra_build_lists(extra_build_lists, save_to_platform)
-
if save_to_platform
-
if save_to_platform.distrib_type == 'rhel'
-
bls = bls.where('
-
(build_lists.arch_id = ? AND projects.publish_i686_into_x86_64 is not true) OR
-
(projects.publish_i686_into_x86_64 is true)
-
', arch_id).joins(:project)
-
else
-
bls = bls.where(arch_id: arch_id)
-
end
-
end
-
self.extra_build_lists = bls.pluck(Arel.sql('build_lists.id'))
-
end
-
-
1
def prepare_auto_publish_status
-
3
if external_nodes.present?
-
self.auto_publish_status = AUTO_PUBLISH_STATUS_NONE
-
end
-
3
if auto_publish? && save_to_repository && !save_to_repository.publish_without_qa?
-
self.auto_publish_status = AUTO_PUBLISH_STATUS_NONE
-
end
-
3
if auto_publish? || auto_publish_into_testing?
-
3
self.auto_create_container = false
-
end
-
3
true
-
end
-
-
1
def prepare_extra_params
-
3
if extra_params.present?
-
params = extra_params.slice(*BuildList::EXTRA_PARAMS)
-
params.update(params) do |k,v|
-
v.strip.gsub(I18n.t("activerecord.attributes.build_list.extra_params.#{k}"), '').
-
gsub(/[^\w\s\-["]'=]/, '')
-
end
-
self.extra_params = params.select{ |k,v| v.present? }
-
end
-
end
-
end
-
1
class BuildList::Filter
-
1
PER_PAGE = [25, 50, 100]
-
-
1
attr_reader :options
-
-
1
def initialize(project, user, options = {})
-
@project, @user = project, user
-
set_options(options)
-
end
-
-
1
def find
-
build_lists = @project ? @project.build_lists : BuildList.all
-
-
if @options[:id]
-
build_lists = build_lists.where(id: @options[:id])
-
else
-
build_lists =
-
case @options[:ownership]
-
when 'owned'
-
BuildListPolicy::Scope.new(@user, build_lists).owned
-
when 'related'
-
BuildListPolicy::Scope.new(@user, build_lists).related
-
else
-
BuildListPolicy::Scope.new(@user, build_lists).everything
-
end
-
build_lists = build_lists.scoped_to_new_core(@options[:new_core] == '0' ? nil : true) if @options[:new_core].present?
-
if @options[:mass_build_id]
-
build_lists = build_lists.by_mass_build(@options[:mass_build_id] == '-1' ? nil : @options[:mass_build_id])
-
end
-
build_lists = build_lists.for_status(@options[:status])
-
.scoped_to_arch(@options[:arch_id])
-
.scoped_to_save_platform(@options[:save_to_platform_id])
-
.scoped_to_build_for_platform(@options[:build_for_platform_id])
-
.scoped_to_save_to_repository(@options[:save_to_repository_id])
-
.scoped_to_project_version(@options[:project_version])
-
.scoped_to_project_name(@options[:project_name])
-
.for_notified_date_period(@options[:updated_at_start], @options[:updated_at_end])
-
end
-
-
build_lists
-
end
-
-
1
def respond_to?(name)
-
return true if @options.has_key?(name)
-
super
-
end
-
-
1
def method_missing(name, *args, &block)
-
@options.has_key?(name) ? @options[name] : super
-
end
-
-
1
private
-
-
1
def set_options(options)
-
if options.is_a?(ActionController::Parameters)
-
options = options.permit([:ownership, :status, :updated_at_start, :updated_at_end, :arch_id,
-
:save_to_platform_id, :build_for_platform_id, :save_to_repository_id,
-
:is_circle, :project_version, :id, :project_name, :mass_build_id, :new_core]).to_h
-
end
-
@options = HashWithIndifferentAccess.new(options.reverse_merge({
-
ownership: nil,
-
status: nil,
-
updated_at_start: nil,
-
updated_at_end: nil,
-
arch_id: nil,
-
save_to_platform_id: nil,
-
build_for_platform_id: nil,
-
save_to_repository_id: nil,
-
is_circle: nil,
-
project_version: nil,
-
id: nil,
-
project_name: nil,
-
mass_build_id: nil,
-
new_core: nil
-
}))
-
-
@options[:ownership] = @options[:ownership].presence || (@project || !@user ? 'everything' : 'owned')
-
@options[:status] = @options[:status].present? ? @options[:status].to_i : nil
-
@options[:created_at_start] = build_date_from_params(:created_at_start, @options)
-
@options[:created_at_end] = build_date_from_params(:created_at_end, @options)
-
@options[:updated_at_start] = build_date_from_params(:updated_at_start, @options)
-
@options[:updated_at_end] = build_date_from_params(:updated_at_end, @options)
-
@options[:project_version] = @options[:project_version].presence
-
@options[:arch_id] = @options[:arch_id].try(:to_i)
-
@options[:save_to_platform_id] = @options[:save_to_platform_id].try(:to_i)
-
@options[:build_for_platform_id] = @options[:build_for_platform_id].try(:to_i)
-
@options[:save_to_repository_id] = @options[:save_to_repository_id].try(:to_i)
-
@options[:is_circle] = @options[:is_circle].present? ? @options[:is_circle] == "1" : nil
-
@options[:id] = @options[:id].presence
-
@options[:project_name] = @options[:project_name].presence
-
@options[:mass_build_id] = @options[:mass_build_id].presence
-
@options[:new_core] = @options[:new_core].presence
-
end
-
-
1
def build_date_from_params(field_name, params)
-
return nil if params[field_name].blank?
-
params[field_name].strip!
-
return Date.parse(params[field_name]) if params[field_name] =~ /\A\d{2}\/\d{2}\/\d{4}\z/
-
return Time.at(params[field_name].to_i) if params[field_name] =~ /\A\d+\z/
-
nil
-
end
-
end
-
1
class BuildList::Item < ActiveRecord::Base
-
-
1
belongs_to :build_list, touch: true
-
-
# attr_protected :build_list_id
-
-
1
GIT_ERROR = 5
-
-
1
STATUSES = [BuildList::SUCCESS, BuildList::BUILD_ERROR, BuildList::BUILD_STARTED, GIT_ERROR, BuildList::BUILD_CANCELED] # BuildList::DEPENDENCIES_ERROR
-
HUMAN_STATUSES = {
-
1
nil => :unknown,
-
GIT_ERROR => :git_error,
-
# BuildList:DEPENDENCIES_ERROR: :dependencies_error,
-
BuildList::SUCCESS => :success,
-
BuildList::BUILD_STARTED => :build_started,
-
BuildList::BUILD_ERROR => :build_error,
-
BuildList::BUILD_CANCELED => :build_canceled
-
}
-
-
1
scope :recent, -> { order("#{table_name}.level ASC, #{table_name}.name ASC") }
-
-
1
def self.group_by_level
-
groups = []
-
current_level = -1
-
all.recent.find_each do |item|
-
groups << [] if current_level < item.level
-
groups.last << item
-
current_level = item.level
-
end
-
-
groups
-
end
-
-
1
def self.human_status(status)
-
I18n.t("layout.build_lists.items.statuses.#{HUMAN_STATUSES[status]}")
-
end
-
-
1
def human_status
-
self.class.human_status(status)
-
end
-
-
end
-
1
class BuildList::Package < ActiveRecord::Base
-
1
PACKAGE_TYPES = %w(source binary)
-
-
1
belongs_to :build_list, touch: true
-
1
belongs_to :project
-
1
belongs_to :platform
-
-
1
serialize :dependent_packages, Array
-
-
1
validates :build_list, :build_list_id, :project, :project_id,
-
:platform, :platform_id, :fullname,
-
:package_type, :name, :release, :version,
-
presence: true
-
1
validates :package_type, inclusion: PACKAGE_TYPES
-
1
validates :sha1, presence: true, if: Proc.new { |p| p.build_list.new_core? }
-
-
1
default_scope { order("lower(#{table_name}.name) ASC, length(#{table_name}.name) ASC") }
-
-
# Fetches only actual (last publised) packages.
-
1
scope :actual, -> { where(actual: true) }
-
1
scope :by_platform, ->(platform) { where(platform_id: platform) }
-
1
scope :by_name, ->(name) { where(name: name) }
-
1
scope :by_package_type, ->(type) { where(package_type: type) }
-
1
scope :like_name, ->(name) { where("#{table_name}.name ILIKE ?", "%#{name}%") if name.present? }
-
-
1
before_create :set_epoch
-
-
1
def assignee
-
project.maintainer
-
end
-
-
# Comparison between versions
-
# @param [BuildList::Package] other
-
# @return [Number] -1 if +other+ is greater than, 0 if +other+ is equal to,
-
# and +1 if other is less than version.
-
1
def rpmvercmp(other)
-
RPM.compareVREs to_vre_epoch_zero, other.to_vre_epoch_zero
-
end
-
-
1
def self.by_repository(repository, &block)
-
# find_each will batch the results instead of getting all in one go
-
actual.where(
-
build_lists: {save_to_repository_id: repository}
-
).joins(build_list: :save_to_repository).includes(project: :maintainer).find_each do |package|
-
yield package
-
end
-
end
-
-
# Public: Set dependent_packages.
-
1
def dependent_packages=(v)
-
v = v.to_s.split(/\s/).select(&:present?) if v.is_a?(String)
-
write_attribute :dependent_packages, v
-
end
-
-
1
protected
-
-
1
def set_epoch
-
self.epoch = nil if epoch.blank? || epoch == 0
-
end
-
-
# String representation in the form "e:v-r"
-
# @return [String]
-
# @note The epoch is included always. As 0 if not present
-
1
def to_vre_epoch_zero
-
res = []
-
if epoch.present?
-
res << epoch.to_s
-
else
-
res << '0'
-
end
-
if version.present?
-
res << version.to_s
-
else
-
res << ''
-
end
-
if release.present?
-
res << release.to_s
-
else
-
res << ''
-
end
-
res
-
end
-
-
end
-
1
class Collaborator
-
1
include ActiveModel::Conversion
-
1
include ActiveModel::Validations
-
1
include ActiveModel::Serializers::JSON
-
1
extend ActiveModel::Naming
-
-
1
attr_accessor :role, :actor, :project, :relation
-
1
attr_reader :id, :actor_id, :actor_type, :actor_name, :project_id
-
-
1
delegate :new_record?, to: :relation
-
-
1
class << self
-
1
def find_by_project(project)
-
res = []
-
project.relations.each do |r|
-
res << from_relation(r) unless project.owner_id == r.actor_id and project.owner_type == r.actor_type
-
end
-
return res
-
end
-
-
1
def find(id)
-
return self.from_relation(Relation.find(id)) || nil
-
end
-
-
1
def create(args)
-
c = self.new(args)
-
return c.save ? c : false
-
end
-
-
1
def create!(args)
-
c = self.new(args)
-
c.save!
-
return c
-
end
-
end
-
-
1
def initialize(args = {})
-
return false if args.blank?
-
args.to_options!
-
acc_options = args.select{ |(k, v)| k.in? [:actor, :project, :relation] }
-
acc_options.each_pair do |name, value|
-
send("#{name}=", value)
-
end
-
-
if args[:project_id].present?
-
@project = Project.find(args[:project_id])
-
end
-
if args[:actor_id].present? and args[:actor_type].present?
-
@actor = args[:actor_type].classify.constantize.find(args[:actor_id])
-
end
-
-
relation.role = args[:role] if args[:role].present? #if @relation.present? and args[:role].present?
-
end
-
-
1
def update(attributes, options = {})
-
attributes.each_pair do |k, v|
-
send("#{k}=", v)
-
end
-
save
-
end
-
-
1
def relation=(model)
-
@relation = model
-
@actor = @relation.actor
-
@project = @relation.target
-
end
-
-
1
def id
-
relation.try(:id)
-
end
-
-
1
def actor_id
-
@actor.try(:id)
-
end
-
-
1
def actor_type
-
@actor.class.to_s.underscore
-
end
-
-
1
def actor_name
-
if @actor.present?
-
@actor.instance_of?(User) ? "#{@actor.uname}#{ @actor.try(:name) and !@actor.name.empty? ? " (#{@actor.name})" : ''}" : @actor.uname
-
else
-
nil
-
end
-
end
-
-
1
def actor_uname
-
@actor.uname
-
end
-
-
1
def project_id
-
@project.try(:id)
-
end
-
-
1
def role
-
relation.try(:role)
-
end
-
-
1
def role=(arg)
-
relation.role = arg
-
end
-
-
1
def save
-
relation.try(:save)
-
end
-
-
1
def save!
-
relation.try(:save!)
-
end
-
-
1
def destroy
-
relation.try(:destroy)
-
@actor.check_assigned_issues @project
-
end
-
-
1
def attributes
-
%w{ id actor_id actor_type actor_name project_id role}.inject({}) do |h, e|
-
h.merge(e => send(e))
-
end
-
end
-
-
1
def persisted?
-
false
-
end
-
-
1
protected
-
-
1
class << self
-
-
1
def from_relation(relation)
-
return nil unless relation.present?
-
return self.new(relation: relation)
-
end
-
-
end
-
-
1
def relation
-
return @relation if @relation.present? and @relation.actor == @actor and @relation.target == @project
-
-
if @actor.present? and @project.present?
-
@relation = Relation.by_actor(@actor).by_target(@project).limit(1).first
-
@relation ||= Relation.new(:actor_id => @actor.id, :actor_type => @actor.class.to_s,
-
target_id: @project.id, target_type: 'Project')
-
else
-
@relation = Relation.new
-
@relation.actor = @actor
-
@relation.target = @project
-
end
-
@relation
-
end
-
-
end
-
1
Collaborator.include_root_in_json = false
-
1
class Comment < ActiveRecord::Base
-
1
include Feed::Comment
-
-
# regexp take from http://code.google.com/p/concerto-platform/source/browse/v3/cms/lib/CodeMirror/mode/gfm/gfm.js?spec=svn861&r=861#71
-
# User/Project#Num
-
# User#Num
-
# #Num
-
1
ISSUES_REGEX = /(?:[a-zA-Z0-9\-_]*\/)?(?:[a-zA-Z0-9\-_]*)?#[0-9]+/
-
-
1
belongs_to :user
-
1
belongs_to :project
-
1
serialize :data
-
-
1
validates :body, :user, :commentable_id, :commentable_type, :project_id, presence: true
-
1
validates :body, length: { maximum: 10000 }
-
-
1
scope :for_commit, ->(c) { where(commentable_id: c.id.hex, commentable_type: c.class) }
-
1
default_scope { order(:created_at) }
-
-
1
before_save :touch_commentable
-
1
after_create :subscribe_on_reply, unless: ->(c) { c.commit_comment? }
-
1
after_create :subscribe_users
-
-
1
def commentable
-
if commit_comment?
-
project.repo.commit(Comment.hex_to_commit_hash commentable_id)
-
else
-
commentable_type.constantize.find_by_id(commentable_id)
-
end
-
end
-
-
1
def commentable=(c)
-
if self.class.commit_comment?(c.class)
-
self.commentable_id = c.id.hex
-
else
-
self.commentable_id = c.id
-
end
-
self.commentable_type = c.class.name
-
end
-
-
1
def self.commit_comment?(class_name)
-
class_name.to_s == 'Grit::Commit'
-
end
-
-
1
def commit_comment?
-
self.class.commit_comment?(commentable_type)
-
end
-
-
1
def self.issue_comment?(class_name)
-
class_name.to_s == 'Issue'
-
end
-
-
1
def issue_comment?
-
self.class.issue_comment?(commentable_type)
-
end
-
-
1
def own_comment?(user)
-
user_id == user.id
-
end
-
-
1
def actual_inline_comment?(diff = nil, force = false)
-
unless force
-
raise "This is not inline comment!" if data.blank? # for debug
-
return data[:actual] unless data[:actual].nil?
-
return false if diff.nil?
-
end
-
return data[:actual] = true if commentable_type == 'Grit::Commit'
-
filepath, line_number = data[:path], data[:line]
-
diff_path = (diff || commentable.show ).select {|d| d.a_path == data[:path]}
-
comment_line = data[:line].to_i
-
# NB! also dont create a comment to the diff header
-
return data[:actual] = false if diff_path.blank? || comment_line == 0
-
res, ind = true, 0
-
diff_path[0].diff.each_line do |line|
-
if self.persisted? && (comment_line-2..comment_line+2).include?(ind) && data.try('[]', "line#{ind-comment_line}") != line.chomp
-
break res = false
-
end
-
ind = ind + 1
-
end
-
if ind < comment_line
-
return data[:actual] = false
-
else
-
return data[:actual] = res
-
end
-
end
-
-
1
def inline_diff
-
data[:strings] + data['line0']
-
end
-
-
1
def pull_comment?
-
commentable.is_a?(Issue) && commentable.pull_request.present?
-
end
-
-
1
def set_additional_data params
-
return true if params[:path].blank? && params[:line].blank? # not inline comment
-
if params[:in_reply].present? && reply = Comment.where(id: params[:in_reply]).first
-
self.data = reply.data
-
return true
-
end
-
self.data = {path: params[:path], line: params[:line]}
-
return actual_inline_comment?(nil, true) if commentable.is_a?(Grit::Commit)
-
if commentable.is_a?(Issue) && pull = commentable.pull_request
-
diff_path = pull.diff.select {|d| d.a_path == params[:path]}
-
return false unless actual_inline_comment?(pull.diff, true)
-
-
comment_line, line_number, strings = params[:line].to_i, -1, []
-
diff_path[0].diff.each_line do |line|
-
line_number = line_number.succ
-
# Save 2 lines above and bottom of the diff comment line
-
break if line_number > comment_line + 2
-
if (comment_line-2..comment_line+2).include? line_number
-
data["line#{line_number-comment_line}"] = line.chomp
-
end
-
-
# Save lines from the closest header for rendering in the discussion
-
if line_number < comment_line
-
# Header is the line like "@@ -47,9 +50,8 @@ def initialize(user)"
-
if line =~ Diff::Display::Unified::Generator::LINE_NUM_RE
-
strings = [line]
-
else
-
strings << line
-
end
-
end
-
end
-
## Bug with numbers of diff lines, now store all diff
-
data[:strings] = strings.join
-
# Limit stored diff to 10 lines (see inline_diff)
-
#data[:strings] = ((strings.count) <= 9 ? strings : [strings[0]] + strings.last(8)).join
-
##
-
data[:view_path] = h(diff_path[0].renamed_file ? "#{diff_path[0].a_path.rtruncate 60} -> #{diff_path[0].b_path.rtruncate 60}" : diff_path[0].a_path.rtruncate(120))
-
end
-
return true
-
end
-
-
1
def self.create_link_on_issues_from_item item, commits = nil
-
linker = item.user
-
-
case
-
when item.is_a?(GitHook)
-
elements = commits
-
opts = {}
-
when item.is_a?(Issue)
-
elements = [[item, item.title], [item, item.body]]
-
opts = {created_from_issue_id: item.id}
-
when item.commentable_type == 'Issue'
-
elements = [[item, item.body]]
-
opts = {created_from_issue_id: item.commentable_id}
-
when item.commentable_type == 'Grit::Commit'
-
elements = [[item, item.body]]
-
opts = {created_from_commit_hash: item.commentable_id}
-
else
-
raise "Unsupported item type #{item.class.name}!"
-
end
-
-
elements.each do |element|
-
element[1].scan(ISSUES_REGEX).each do |hash|
-
issue = Issue.find_by_hash_tag hash, linker, item.project
-
next unless issue
-
# dont create link to the same issue
-
next if opts[:created_from_issue_id] == issue.id
-
opts = {created_from_commit_hash: element[0].hex} if item.is_a?(GitHook)
-
# dont create duplicate link to issue
-
next if Comment.find_existing_automatic_comment issue, opts
-
# dont create link to outdated commit
-
next if item.is_a?(GitHook) && !item.project.repo.commit(element[0])
-
comment = linker.comments.new body: 'automatic comment'
-
comment.commentable, comment.project, comment.automatic = issue, issue.project, true
-
comment.data = {from_project_id: item.project.id}
-
if opts[:created_from_commit_hash]
-
comment.created_from_commit_hash = opts[:created_from_commit_hash]
-
elsif opts[:created_from_issue_id]
-
comment.data.merge!(comment_id: item.id) if item.is_a? Comment
-
comment.created_from_issue_id = opts[:created_from_issue_id]
-
else
-
raise 'Unsupported opts for automatic comment!'
-
end
-
comment.save
-
end
-
end
-
end
-
-
1
def self.hex_to_commit_hash hex
-
# '079d'.hex.to_s(16) => "79d"
-
t = hex.to_s(16)
-
'0'*(40-t.length) << t # commit hash has 40-character
-
end
-
-
1
protected
-
-
1
def touch_commentable
-
commentable.touch unless commit_comment?
-
end
-
-
1
def subscribe_on_reply
-
commentable.subscribes.where(user_id: user_id).first_or_create
-
end
-
-
1
def subscribe_users
-
if issue_comment?
-
commentable.subscribes.create(user: user) if !commentable.subscribes.exists?(user_id: user.id)
-
elsif commit_comment?
-
recipients = project.all_members
-
recipients << user << User.find_by(email: commentable.try(:committer).try(:email)) # commentor and committer
-
recipients.compact.uniq.each do |user|
-
options = {project_id: project.id, subscribeable_id: commentable_id, subscribeable_type: commentable.class.name, user_id: user.id}
-
Subscribe.subscribe_to_commit(options) if Subscribe.subscribed_to_commit?(project, user, commentable)
-
end
-
end
-
end
-
-
1
def self.find_existing_automatic_comment issue, opts
-
find_dup = opts.merge(automatic: true, commentable_type: issue.class.name,
-
commentable_id: issue.id)
-
Comment.exists? find_dup
-
end
-
end
-
1
module AbfWorkerMethods
-
1
extend ActiveSupport::Concern
-
-
1
MASS_BUILDS_SET = 'abf-worker::mass-builds'
-
1
USER_BUILDS_SET = 'abf-worker::user-builds'
-
-
1
module ClassMethods
-
1
def log_server
-
@log_server ||= Redis.new(url: ENV['REDIS_URL'])
-
end
-
end
-
-
1
def abf_worker_log
-
(self.class.log_server.get(service_queue) || I18n.t('layout.build_lists.log.not_available')).truncate(40000)
-
end
-
-
1
def add_job_to_abf_worker_queue
-
Resque.push(
-
worker_queue_with_priority,
-
'class' => worker_queue_class,
-
'args' => [abf_worker_args]
-
)
-
end
-
-
1
def cancel_job
-
if destroy_from_resque_queue == 1
-
build_canceled
-
elsif
-
send_stop_signal
-
end
-
true
-
end
-
-
1
def destroy_from_resque_queue
-
Resque::Job.destroy(
-
worker_queue_with_priority,
-
worker_queue_class,
-
abf_worker_args
-
)
-
end
-
-
1
def worker_queue_with_priority(prefix = true)
-
queue = ''
-
-
if prefix && is_a?(BuildList)
-
if mass_build_id
-
queue << "mass_build_#{mass_build_id}_"
-
else
-
queue << "user_build_#{user_id}_"
-
end
-
end
-
-
queue << abf_worker_base_queue
-
queue << '_' << abf_worker_priority if abf_worker_priority.present?
-
queue
-
end
-
-
1
def worker_queue_class
-
"AbfWorker::#{abf_worker_base_queue.classify}#{abf_worker_priority.capitalize}"
-
end
-
-
1
private
-
-
1
def send_stop_signal
-
Redis.current.setex(
-
"#{service_queue}::live-inspector",
-
240, # Data will be removed from Redis after 240 sec.
-
'USR1' # Immediately kill child but don't exit
-
)
-
end
-
-
1
def service_queue
-
"abfworker::#{abf_worker_base_queue.gsub(/\_/, '-')}-#{id}"
-
end
-
-
-
end
-
1
module ActsLikeMember
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
2
scope :not_member_of, ->(item) {
-
where("
-
#{table_name}.id NOT IN (
-
SELECT relations.actor_id
-
FROM relations
-
WHERE (
-
relations.actor_type = '#{self.to_s}'
-
AND relations.target_type = '#{item.class.to_s}'
-
AND relations.target_id = #{item.id}
-
)
-
)
-
")
-
}
-
2
scope :search_order, -> { order("CHAR_LENGTH(#{table_name}.uname) ASC") }
-
2
scope :without_ids, ->(a) { where("#{table_name}.id NOT IN (?)", a) }
-
14
scope :by_uname, ->(n) { where("#{table_name}.uname ILIKE ?", n) }
-
2
scope :search_like, ->(q) { by_uname("%#{q.to_s.strip}%") }
-
end
-
-
1
def to_param
-
uname
-
end
-
-
1
module ClassMethods
-
1
def find_by_insensitive_uname(uname)
-
find_by(uname: uname) || by_uname(uname).first
-
end
-
-
1
def find_by_insensitive_uname!(uname)
-
find_by_insensitive_uname(uname) or raise ActiveRecord::RecordNotFound
-
end
-
end
-
end
-
1
module Autostart
-
1
extend ActiveSupport::Concern
-
-
1
ONCE_A_12_HOURS = 0
-
1
ONCE_A_DAY = 1
-
1
ONCE_A_WEEK = 2
-
-
1
AUTOSTART_STATUSES = [ONCE_A_12_HOURS, ONCE_A_DAY, ONCE_A_WEEK]
-
HUMAN_AUTOSTART_STATUSES = {
-
1
ONCE_A_12_HOURS => :once_a_12_hours,
-
ONCE_A_DAY => :once_a_day,
-
ONCE_A_WEEK => :once_a_week
-
}
-
-
1
included do
-
2
validates :autostart_status, numericality: true,
-
inclusion: {in: AUTOSTART_STATUSES}, allow_blank: true
-
end
-
-
1
def human_autostart_status
-
self.class.human_autostart_status(autostart_status)
-
end
-
-
1
module ClassMethods
-
1
def human_autostart_status(autostart_status)
-
I18n.t("layout.products.autostart_statuses.#{HUMAN_AUTOSTART_STATUSES[autostart_status]}")
-
end
-
end
-
end
-
1
module BuildListObserver
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
before_update :update_average_build_time
-
1
before_update :update_statistic
-
end
-
-
1
private
-
-
1
def update_statistic
-
3
Statistic.statsd_increment(
-
activity_at: Time.now,
-
key: "#{Statistic::KEY_BUILD_LIST}.#{status}",
-
project_id: project_id,
-
user_id: user_id,
-
3
) if status_changed?
-
end
-
-
1
def update_average_build_time
-
3
if status_changed?
-
3
self.started_at = Time.now if status == self.class::BUILD_STARTED
-
3
if [self.class::BUILD_ERROR,
-
self.class::SUCCESS,
-
self.class::BUILD_CANCELING,
-
self.class::TESTS_FAILED,
-
self.class::BUILD_CANCELED].include? status
-
# stores time interval beetwin build start and finish in seconds
-
self.duration = current_duration if self.started_at
-
-
if status == self.class::SUCCESS
-
# Update project average build time
-
begin
-
statistic = project.project_statistics.where(arch_id: arch_id).first_or_create
-
rescue ActiveRecord::RecordNotUnique
-
retry
-
end
-
build_count = statistic.build_count.to_i
-
new_av_time = ( statistic.average_build_time * build_count + duration.to_i ) / ( build_count + 1 )
-
statistic.update(average_build_time: new_av_time, build_count: build_count + 1)
-
end
-
end
-
end
-
end
-
end
-
1
module CommitAndVersion
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
-
2
validate -> {
-
6
if project && (commit_hash.blank? || project.repo.commit(commit_hash).blank?)
-
errors.add :commit_hash, I18n.t('flash.build_list.wrong_commit_hash', commit_hash: commit_hash)
-
end
-
}
-
-
2
before_validation :set_commit_and_version
-
2
before_create :set_last_published_commit
-
end
-
-
1
protected
-
-
1
def set_commit_and_version
-
6
if project && project_version.present? && commit_hash.blank?
-
self.commit_hash = project.repo.commits(project_version).try(:first).try(:id)
-
6
elsif project_version.blank? && commit_hash.present?
-
self.project_version = commit_hash
-
end
-
end
-
-
1
def set_last_published_commit
-
3
return unless self.respond_to? :last_published_commit_hash # product?
-
3
last_commit = self.last_published.first.try :commit_hash
-
3
if last_commit && self.project.repo.commit(last_commit).present? # commit(nil) is not nil!
-
self.last_published_commit_hash = last_commit
-
end
-
end
-
end
-
1
module DefaultBranchable
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
3
validates :default_branch,
-
length: { maximum: 100 }
-
end
-
-
end
-
1
module EmptyMetadata
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
2
after_create :create_empty_metadata
-
end
-
-
1
def create_empty_metadata
-
return if is_a?(Platform) && ( personal? || hidden? )
-
Resque.enqueue(CreateEmptyMetadataJob, self.class.name, id)
-
end
-
-
end
-
1
module EventLoggable
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
7
after_create :log_creation_event
-
7
after_destroy :log_destroying_event
-
end
-
-
1
private
-
-
1
def log_creation_event
-
54
ActiveSupport::Notifications.instrument(self.class.name, eventable: self)
-
end
-
-
1
def log_before_update
-
case self.class.to_s
-
when 'BuildList'
-
if status_changed? and [BuildList::BUILD_CANCELED, BuildList::BUILD_PUBLISHED].include?(status)
-
ActiveSupport::Notifications.instrument("event_log.observer", eventable: self)
-
end
-
when 'Platform'
-
if self.visibility_changed?
-
ActiveSupport::Notifications.instrument "event_log.observer", eventable: self,
-
message: I18n.t("activeself.attributes.platform.visibility_types.#{visibility}")
-
end
-
end
-
end
-
-
1
def log_destroying_event
-
ActiveSupport::Notifications.instrument(self.class.name, eventable: self)
-
end
-
end
-
1
module ExternalNodable
-
1
extend ActiveSupport::Concern
-
-
1
EXTERNAL_NODES = %w(owned everything)
-
-
1
included do
-
3
validates :external_nodes,
-
inclusion: { in: EXTERNAL_NODES },
-
allow_blank: true
-
end
-
-
end
-
1
module Feed::BuildList
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
after_update :build_list_notifications
-
end
-
-
1
private
-
-
1
def build_list_notifications
-
3
if mass_build.blank? && ( # Do not show mass build activity in activity feeds
-
status_changed? && [
-
BuildList::BUILD_PENDING,
-
BuildList::BUILD_PUBLISHED,
-
BuildList::SUCCESS,
-
BuildList::BUILD_ERROR,
-
BuildList::FAILED_PUBLISH,
-
BuildList::TESTS_FAILED
-
].include?(status)
-
)
-
-
updater = publisher || user
-
(project.all_members | [publisher]).compact.each do |recipient|
-
ActivityFeed.create(
-
user: recipient,
-
kind: 'build_list_notification',
-
project_owner: project.owner_uname,
-
project_name: project.name,
-
creator_id: updater.id,
-
data: {
-
build_list_id: id,
-
status: status,
-
updated_at: updated_at,
-
project_id: project_id,
-
creator_name: updater.name,
-
creator_email: updater.email
-
}
-
)
-
end
-
-
end
-
end
-
-
end
-
1
module Feed::Comment
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
after_commit :new_comment_notifications, on: :create
-
# dont remove outdated issues link
-
1
after_update -> { Comment.create_link_on_issues_from_item(self) }
-
end
-
-
1
private
-
-
1
def new_comment_notifications
-
return if automatic?
-
-
if issue_comment?
-
commentable.subscribes.each do |subscribe|
-
if can_notify_on_new_comment?(subscribe)
-
UserMailer.new_comment_notification(self, subscribe.user_id).deliver unless own_comment?(subscribe.user)
-
ActivityFeed.create(
-
user_id: subscribe.user_id,
-
kind: 'new_comment_notification',
-
project_owner: project.owner_uname,
-
project_name: project.name,
-
creator_id: user_id,
-
data: {
-
creator_name: user.name,
-
creator_email: user.email,
-
comment_body: body.truncate(100, omission: '…'),
-
issue_title: commentable.title,
-
issue_serial_id: commentable.serial_id,
-
project_id: commentable.project.id,
-
comment_id: id
-
}
-
)
-
end
-
end
-
elsif commit_comment?
-
Subscribe.comment_subscribes(self).where(status: true).each do |subscribe|
-
next if !subscribe.user_id
-
if subscribe.user.notifier.can_notify && !own_comment?(subscribe.user)
-
( (subscribe.project.owner?(subscribe.user) && subscribe.user.notifier.new_comment_commit_repo_owner) ||
-
(subscribe.user.commentor?(self.commentable) && subscribe.user.notifier.new_comment_commit_commentor) ||
-
(subscribe.user.committer?(self.commentable) && subscribe.user.notifier.new_comment_commit_owner) )
-
UserMailer.new_comment_notification(self, subscribe.user_id).deliver
-
end
-
ActivityFeed.create(
-
user_id: subscribe.user_id,
-
kind: 'new_comment_commit_notification',
-
project_owner: project.owner_uname,
-
project_name: project.name,
-
creator_id: user_id,
-
data: {
-
creator_name: user.name,
-
creator_email: user.email,
-
-
comment_body: body.truncate(100, omission: '…'),
-
commit_message: commentable.message.truncate(70, omission: '…'),
-
commit_id: commentable.id,
-
project_id: project.id,
-
comment_id: id
-
}
-
)
-
end
-
end
-
Comment.create_link_on_issues_from_item(self)
-
end
-
-
1
def can_notify_on_new_comment?(subscribe)
-
notifier = SettingsNotifier.find_by user_id: subscribe.user_id
-
notifier && notifier.new_comment && notifier.can_notify
-
end
-
end
-
1
module Feed::Git
-
-
1
def self.create_notifications(record)
-
-
case record.class.to_s
-
when 'GitHook'
-
return unless record.project
-
PullRequest.where("from_project_id = ? OR to_project_id = ?", record.project, record.project).needed_checking.each {|pull| pull.check}
-
record.project.hooks.each{ |h| h.receive_push(record) }
-
-
change_type = record.change_type
-
branch_name = record.refname.split('/').last
-
-
if change_type == 'delete'
-
kind = 'git_delete_branch_notification'
-
options = {project_id: record.project.id, branch_name: branch_name, change_type: change_type}
-
else
-
if record.message # online update
-
last_commits, commits = [[record.newrev, record.message.truncate(70, omission: '…')]], []
-
all_commits = last_commits
-
else
-
commits = record.project.repo.commits_between(record.oldrev, record.newrev)
-
all_commits = commits.collect { |commit| [commit.sha, commit.message.truncate(70, omission: '…')] }
-
last_commits = all_commits.last(3).reverse
-
end
-
-
kind = 'git_new_push_notification'
-
options = {project_id: record.project.id, last_commits: last_commits,
-
branch_name: branch_name, change_type: change_type}
-
if commits.count > 3
-
commits = commits[0...-3]
-
options.merge!({other_commits_count: commits.count, other_commits: "#{commits[0].sha[0..9]}...#{commits[-1].sha[0..9]}"})
-
end
-
-
if all_commits.count > 0
-
Statistic.statsd_increment(
-
activity_at: Time.now,
-
key: Statistic::KEY_COMMIT,
-
project_id: record.project.id,
-
user_id: record.user.id,
-
counter: all_commits.count
-
)
-
Comment.create_link_on_issues_from_item(record, all_commits)
-
end
-
end
-
options.merge!({creator_name: record.user.name, creator_email: record.user.email}) if record.user
-
-
options_for_mail = options.merge(project_owner: record.project.owner_uname,
-
project_name: record.project.name)
-
record.project.all_members.each do |recipient|
-
ActivityFeed.create!(
-
user: recipient,
-
kind: kind,
-
project_owner: record.project.owner_uname,
-
project_name: record.project.name,
-
creator_id: record.user.id,
-
data: options
-
)
-
next if record.user && record.user.id == recipient.id
-
if recipient.notifier.can_notify && recipient.notifier.update_code
-
UserMailer.send(kind, recipient, options_for_mail).deliver
-
end
-
end
-
-
when 'Hash' # 'Gollum::Committer'
-
actor = User.find_by! uname: record[:actor_name]
-
project = Project.find record[:project_id]
-
-
project.all_members.each do |recipient|
-
ActivityFeed.create!(
-
user: recipient,
-
kind: 'wiki_new_commit_notification',
-
project_owner: project.owner_uname,
-
project_name: project.name,
-
creator_id: actor.id,
-
data: {creator_name: actor.name, creator_email: actor.email,
-
project_id: project.id, commit_sha: record[:commit_sha]}
-
)
-
end
-
end
-
end
-
end
-
1
module Feed::Issue
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
after_commit :new_issue_notifications, on: :create
-
-
1
after_commit :send_assign_notifications, on: :create, if: ->(i) { i.assignee }
-
1
after_update :send_assign_notifications
-
-
1
after_commit :send_hooks, on: :create
-
1
after_update -> { send_hooks(:update) }, if: ->(i) { i.previous_changes['status'].present? }
-
end
-
-
1
private
-
-
1
def new_issue_notifications
-
return unless user
-
collect_recipients.each do |recipient|
-
if user_id != recipient.id && recipient.notifier.can_notify &&
-
recipient.notifier.new_issue && assignee_id != recipient.id
-
UserMailer.new_issue_notification(id, recipient.id).deliver
-
end
-
ActivityFeed.create(
-
user: recipient,
-
kind: 'new_issue_notification',
-
project_owner: project.owner_uname,
-
project_name: project.name,
-
creator_id: user_id,
-
data: {
-
creator_name: user.name,
-
creator_email: user.email,
-
issue_serial_id: serial_id,
-
issue_title: title,
-
project_id: project.id
-
}
-
)
-
end
-
::Comment.create_link_on_issues_from_item(self)
-
end
-
-
1
def send_assign_notifications
-
return if @skip_assign_notifications
-
@skip_assign_notifications = true
-
if assignee_id && (new_pull_request || saved_change_to_assignee_id?)
-
if assignee.notifier.issue_assign && assignee.notifier.can_notify
-
UserMailer.issue_assign_notification(self, assignee).deliver
-
end
-
ActivityFeed.create(
-
user: assignee,
-
kind: 'issue_assign_notification',
-
project_owner: project.owner_uname,
-
project_name: project.name,
-
data: {
-
user_name: assignee.name,
-
user_email: assignee.email,
-
issue_serial_id: serial_id,
-
issue_title: title,
-
project_id: project.id
-
}
-
)
-
end
-
# dont remove outdated issues link
-
::Comment.create_link_on_issues_from_item(self) if saved_change_to_title? ||
-
saved_change_to_body?
-
end
-
-
1
def send_hooks(action = :create)
-
project.hooks.each{ |h| h.receive_issues(self, action) }
-
end
-
end
-
1
module Feed::User
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
after_commit :new_user_notification, on: :create
-
end
-
-
1
private
-
-
1
def new_user_notification
-
24
activity_feeds.create(
-
kind: 'new_user_notification',
-
data: { user_name: user_appeal, user_email: email }
-
)
-
end
-
-
end
-
1
module FileStoreClean
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
5
later :destroy, queue: :middle
-
5
later :later_destroy_files_from_file_store, queue: :middle
-
end
-
-
1
def destroy
-
destroy_files_from_file_store if Rails.env.production?
-
super
-
end
-
-
1
def sha1_of_file_store_files
-
raise NotImplementedError, "You should implement this method"
-
end
-
-
1
def destroy_files_from_file_store(args = sha1_of_file_store_files)
-
files = *args
-
files.each do |sha1|
-
FileStoreService::File.new(sha1: sha1).destroy
-
end
-
end
-
-
1
def later_destroy_files_from_file_store(args)
-
destroy_files_from_file_store(args)
-
end
-
-
end
-
# Private: Finders of all sorts: methods to find FlashNotify records, methods to find
-
# other records which belong to given FlashNotify.
-
#
-
# This module gets included into FlashNotify.
-
1
module FlashNotify::Finders
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
scope :published, -> { where(published: true) }
-
-
1
after_commit :clear_caches
-
1
after_touch :clear_caches
-
end
-
-
1
module ClassMethods
-
-
# Public: Get cached first published FlashNotify record.
-
#
-
# Returns FlashNotify record or nil.
-
1
def published_first_cached
-
Rails.cache.fetch('FlashNotify.published.first') do
-
published.first
-
end
-
end
-
end
-
-
1
protected
-
-
# Private: after_commit and after_touch hook which clears find_cached cache.
-
1
def clear_caches
-
Rails.cache.delete('FlashNotify.published.first')
-
end
-
end
-
1
require 'nokogiri'
-
1
require 'open-uri'
-
-
1
module Git
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
CONTENT_LIMIT = 100
-
-
1
has_attached_file :srpm
-
-
1
validates_attachment_size :srpm, less_than_or_equal_to: 500.megabytes
-
1
validates_attachment_content_type :srpm, content_type: ['application/octet-stream', "application/x-rpm", "application/x-redhat-package-manager"], message: I18n.t('layout.invalid_content_type')
-
-
1
after_create :create_git_repo
-
4
after_commit(on: :create) {|p| p.fork_git_repo unless p.is_root?} # later with resque
-
4
after_commit(on: :create) {|p| p.import_attached_srpm if p.srpm?} # later with resque # should be after create_git_repo
-
1
after_destroy :destroy_git_repo
-
# after_rollback -> { destroy_git_repo rescue true if new_record? }
-
-
1
later :import_attached_srpm, queue: :fork_import
-
1
later :fork_git_repo, queue: :fork_import
-
end
-
-
1
def repo
-
begin
-
9
@repo ||= Grit::Repo.new(path)
-
rescue => e
-
3
if !e.is_a?(Grit::NoSuchPathError) && !e.is_a?(Rugged::RepositoryError)
-
Raven.capture_exception(e)
-
end
-
3
Grit::Repo.new(GAP_REPO_PATH)
-
end
-
end
-
-
1
def path
-
21
build_path(name_with_owner)
-
end
-
-
1
def versions
-
repo.tags.map(&:name) + repo.branches.map(&:name)
-
end
-
-
1
def find_blob_and_raw_of_spec_file(project_version)
-
blob = repo.tree(project_version).contents.find{ |n| n.is_a?(Grit::Blob) && n.name =~ /.spec$/ }
-
return unless blob
-
-
raw = Grit::GitRuby::Repository.new(repo.path).get_raw_object_by_sha1(blob.id)
-
[blob, raw]
-
end
-
-
1
def create_branch(new_ref, from_ref, user)
-
return false if new_ref.blank? || from_ref.blank? || !(from_commit = repo.commit(from_ref))
-
status, out, err = repo.git.native(:branch, {process_info: true}, new_ref, from_commit.id)
-
if status == 0
-
Resque.enqueue(GitHook, owner.uname, name, from_commit.id, GitHook::ZERO, "refs/heads/#{new_ref}", 'commit', "user-#{user.id}", nil)
-
return true
-
end
-
return false
-
-
end
-
-
1
def delete_branch(branch, user)
-
return false if default_branch == branch.name
-
message = repo.git.native(:branch, {}, '-D', branch.name)
-
if message.present?
-
Resque.enqueue(GitHook, owner.uname, name, GitHook::ZERO, branch.commit.id, "refs/heads/#{branch.name}", 'commit', "user-#{user.id}", message)
-
end
-
return message.present?
-
end
-
-
1
def update_file(path, data, options = {})
-
head = options[:head].to_s || default_branch
-
actor = get_actor(options[:actor])
-
filename = File.split(path).last
-
message = options[:message]
-
message = "Updated file #{filename}" if message.nil? or message.empty?
-
-
# can not write to unexisted branch
-
return false if repo.branches.select{|b| b.name == head}.size != 1
-
-
parent = repo.commits(head).first
-
-
index = repo.index
-
index.read_tree(parent.tree.id)
-
-
# can not create new file
-
return false if (index.current_tree / path).nil?
-
-
system "sudo chown -R rosa:rosa #{repo.path}" #FIXME Permission denied - /mnt/gitstore/git_projects/...
-
index.add(path, data)
-
if sha1 = index.commit(message, parents: [parent], actor: actor, last_tree: parent.tree.id, head: head)
-
Resque.enqueue(GitHook, owner.uname, name, sha1, sha1, "refs/heads/#{head}", 'commit', "user-#{options[:actor].id}", message)
-
end
-
sha1
-
end
-
-
1
def paginate_commits(treeish, options = {})
-
options[:page] = options[:page].try(:to_i) || 1
-
options[:per_page] = options[:per_page].try(:to_i) || 20
-
-
skip = options[:per_page] * (options[:page] - 1)
-
last_page = (skip + options[:per_page]) >= repo.commit_count(treeish)
-
-
[repo.commits(treeish, options[:per_page], skip), options[:page], last_page]
-
end
-
-
1
def tree_info(tree, treeish = nil, path = nil, page = 0)
-
return [] unless tree
-
grouped = tree.contents.sort_by{|c| c.name.downcase}.group_by(&:class)
-
contents = [
-
grouped[Grit::Tree],
-
grouped[Grit::Blob],
-
grouped[Grit::Submodule]
-
].compact.flatten
-
range = page*CONTENT_LIMIT..CONTENT_LIMIT+page*(CONTENT_LIMIT)-1
-
contents[range].map do |node|
-
node_path = File.join([path.present? ? path : nil, node.name].compact)
-
[
-
node,
-
node_path,
-
repo.log(treeish, node_path, max_count: 1).first
-
]
-
end
-
end
-
-
1
def import_srpm(srpm_path = srpm.path, branch_name = 'import')
-
token = User.find_by(uname: 'rosa_system').authentication_token
-
opts = [srpm_path, path, branch_name, Rails.root.join('bin', 'file-store.rb'), token, APP_CONFIG['file_store_url']].join(' ')
-
system("#{Rails.root.join('bin', 'import_srpm.sh')} #{opts} >> /dev/null 2>&1")
-
end
-
-
1
def is_empty?
-
repo.branches.count == 0
-
end
-
-
1
def total_commits_count
-
return 0 if is_empty?
-
%x(cd #{path} && git rev-list --all | wc -l).to_i
-
end
-
-
1
protected
-
-
1
def aliases_path
-
File.join(APP_CONFIG['git_path'], 'git_projects', '.aliases')
-
end
-
-
1
def alias_path
-
File.join(aliases_path, "#{alias_from_id}.git")
-
end
-
-
1
def build_path(dir)
-
21
File.join(APP_CONFIG['git_path'], 'git_projects', "#{dir}.git")
-
end
-
-
1
def import_attached_srpm
-
if srpm?
-
import_srpm # srpm.path
-
self.srpm = nil; save # clear srpm
-
end
-
end
-
-
1
def create_git_repo
-
3
if is_root?
-
3
Grit::Repo.init_bare(path)
-
3
write_hook
-
end
-
end
-
-
# Creates fork/alias for GIT repo
-
1
def fork_git_repo
-
dummy = Grit::Repo.new(path) rescue nil
-
# Do nothing if GIT repo already exist
-
unless dummy
-
if alias_from_id
-
FileUtils.mkdir_p(aliases_path)
-
if !Dir.exists?(alias_path) && alias_from
-
# Move GIT repo into aliases
-
FileUtils.mv(alias_from.path, alias_path, force: true)
-
# Create link for GIT
-
FileUtils.ln_sf alias_path, alias_from.path
-
end
-
# Create folder
-
FileUtils.mkdir_p File.join(APP_CONFIG['git_path'], 'git_projects', owner_uname || owner.uname)
-
# Create link for GIT
-
FileUtils.ln_sf alias_path, path
-
else
-
parent.repo.fork_bare(path, shared: false)
-
end
-
end
-
write_hook
-
end
-
-
1
def destroy_git_repo
-
FileUtils.rm_rf path
-
return unless alias_from_id
-
unless alias_from || Project.where.not(id: id).where(alias_from_id: alias_from_id).exists?
-
FileUtils.rm_rf alias_path
-
end
-
end
-
-
1
def write_hook
-
3
hook = "/home/#{APP_CONFIG['shell_user']}/gitlab-shell/hooks/post-receive"
-
3
hook_file = File.join(path, 'hooks', 'post-receive')
-
3
FileUtils.ln_sf hook, hook_file
-
end
-
-
1
def get_actor(actor = nil)
-
@last_actor = case actor.class.to_s
-
when 'Grit::Actor' then options[:actor]
-
when 'Hash' then Grit::Actor.new(actor[:name], actor[:email])
-
when 'String' then Grit::Actor.from_stirng(actor)
-
else begin
-
if actor.respond_to?(:name) and actor.respond_to?(:email)
-
Grit::Actor.new(actor.name, actor.email)
-
else
-
config = Grit::Config.new(repo)
-
Grit::Actor.new(config['user.name'], config['user.email'])
-
end
-
end
-
end
-
@last_actor
-
end
-
-
1
module ClassMethods
-
1
MAX_SRC_SIZE = 1024*1024*256
-
-
1
def process_hook(owner_uname, repo, newrev, oldrev, ref, newrev_type, user = nil, message = nil)
-
rec = GitHook.new(owner_uname, repo, newrev, oldrev, ref, newrev_type, user, message)
-
Modules::Observers::ActivityFeed::Git.create_notifications rec
-
end
-
-
1
def run_mass_import(url, srpms_list, visibility, owner, add_to_repository_id)
-
doc = Nokogiri::HTML(open(url))
-
links = doc.css("a[href$='.src.rpm']")
-
return if links.count == 0
-
filter = srpms_list.lines.map(&:chomp).map(&:strip).select(&:present?)
-
-
repository = Repository.find add_to_repository_id
-
platform = repository.platform
-
dir = Dir.mktmpdir 'mass-import-', APP_CONFIG['tmpfs_path']
-
links.each do |link|
-
begin
-
package = link.attributes['href'].value
-
package.chomp!; package.strip!
-
-
next if package.size == 0 || package !~ Project::NAME_REGEXP
-
next if filter.present? && !filter.include?(package)
-
-
uri = URI "#{url}/#{package}"
-
srpm_file = "#{dir}/#{package}"
-
Net::HTTP.start(uri.host) do |http|
-
if http.request_head(uri.path)['content-length'].to_i < MAX_SRC_SIZE
-
f = open(srpm_file, 'wb')
-
http.request_get(uri.path) do |resp|
-
resp.read_body{ |segment| f.write(segment) }
-
end
-
f.close
-
end
-
end
-
if name = `rpm -q --qf '[%{Name}]' -p #{srpm_file}` and $?.success? and name.present?
-
next if owner.projects.exists?(name: name)
-
description = `rpm -q --qf '[%{Description}]' -p #{srpm_file}`.scrub('')
-
-
project = owner.projects.build(
-
name: name,
-
description: description,
-
visibility: visibility,
-
is_package: false # See: Hook for #attach_to_personal_repository
-
)
-
project.owner = owner
-
if project.save
-
repository.projects << project rescue nil
-
project.update(is_package: true)
-
project.import_srpm srpm_file, platform.name
-
end
-
end
-
rescue => e
-
f.close if defined?(f)
-
Raven.capture_exception(e, extra: {
-
link: link.to_s,
-
url: url,
-
owner: owner
-
})
-
ensure
-
File.delete srpm_file if srpm_file
-
end
-
end
-
rescue => e
-
Raven.capture_exception(e, extra: {
-
url: url,
-
owner: owner
-
})
-
ensure
-
FileUtils.remove_entry_secure dir if dir
-
end
-
end
-
end
-
1
module Owner
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
2
validates :owner, presence: true
-
2
after_create do
-
21
relations.create(actor: owner, role: 'admin')
-
end
-
end
-
end
-
1
module PersonalRepository
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
2
after_create :create_personal_repository, unless: :system?
-
end
-
-
1
def create_personal_repository
-
begin
-
12
pl = own_platforms.build
-
12
pl.owner = self
-
12
pl.name = "#{self.uname}_personal"
-
12
pl.default_branch = pl.name
-
12
pl.description = "#{self.uname}_personal"
-
12
pl.platform_type = Platform::TYPE_PERSONAL
-
12
pl.distrib_type = APP_CONFIG['distr_types'].first
-
12
pl.visibility = Platform::VISIBILITY_OPEN
-
12
pl.save!
-
-
12
rep = pl.repositories.build
-
12
rep.name = 'main'
-
12
rep.description = 'main'
-
12
rep.save!
-
rescue Exception => e
-
pl.now_destroy rescue false
-
raise e
-
end
-
12
return true
-
end
-
-
1
def personal_platform
-
6
own_platforms.personal.first
-
end
-
-
1
def personal_repository
-
3
personal_platform.repositories.first
-
end
-
end
-
# Private: Finders of all sorts: methods to find Platform records, methods to find
-
# other records which belong to given Platform.
-
#
-
# This module gets included into Platform.
-
1
module Platform::Finders
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
-
1
scope :search_order, -> { order(:name) }
-
1
scope :search_like, -> (q) { where("#{table_name}.name ILIKE ?", "%#{q.to_s.strip}%") }
-
1
scope :by_visibilities, -> (v) { where(visibility: v) }
-
1
scope :opened, -> { where(visibility: Platform::VISIBILITY_OPEN) }
-
1
scope :hidden, -> { where(visibility: Platform::VISIBILITY_HIDDEN) }
-
7
scope :by_type, -> (type) { where(platform_type: type) if type.present? }
-
1
scope :main, -> { by_type(Platform::TYPE_MAIN) }
-
7
scope :personal, -> { by_type(Platform::TYPE_PERSONAL) }
-
1
scope :waiting_for_regeneration, -> { where(status: Platform::WAITING_FOR_REGENERATION) }
-
-
1
after_commit :clear_caches
-
1
after_touch :clear_caches
-
end
-
-
1
module ClassMethods
-
-
# Public: Get cached Platform record by ID or name.
-
#
-
# platform_id - ID or Name (Numeric/String)
-
#
-
# Returns Platform record.
-
# Raises ActiveRecord::RecordNotFound if nothing was found.
-
1
def find_cached(platform_id)
-
Rails.cache.fetch(['Platform.find', platform_id]) do
-
find(platform_id)
-
end
-
end
-
end
-
-
1
protected
-
-
# Private: after_commit and after_touch hook which clears find_cached cache.
-
1
def clear_caches
-
18
Rails.cache.delete(['Platform.find', id])
-
18
Rails.cache.delete(['Platform.find', name])
-
-
18
if chg = previous_changes["name"]
-
6
Rails.cache.delete(['Platform.find', chg.first])
-
end
-
end
-
end
-
# Internal: various definitions and instance methods related to AbfWorker.
-
#
-
# This module gets mixed in into ProductBuildList class.
-
1
module ProductBuildLists::AbfWorkerable
-
1
extend ActiveSupport::Concern
-
-
1
CACHED_CHROOT_TOKEN_DESCRIPTION = 'cached-chroot'
-
-
1
include AbfWorkerMethods
-
-
1
included do
-
1
delegate :url_helpers, to: 'Rails.application.routes'
-
-
1
after_create :add_job_to_abf_worker_queue
-
end
-
-
-
######################################
-
# Instance methods #
-
######################################
-
-
1
def sha1_of_file_store_files
-
(results || []).map{ |r| r['sha1'] }.compact
-
end
-
-
1
protected
-
-
1
def abf_worker_priority
-
''
-
end
-
-
1
def abf_worker_base_queue
-
'iso_worker'
-
end
-
-
1
def abf_worker_args
-
{
-
id: id,
-
srcpath: abf_worker_srcpath,
-
params: abf_worker_params,
-
time_living: time_living,
-
main_script: main_script,
-
platform: {
-
type: product.platform.distrib_type,
-
name: product.platform.name,
-
arch: arch.name
-
},
-
user: {uname: user.try(:uname), email: user.try(:email)}
-
}
-
end
-
-
# Private: Get URL to project archive.
-
#
-
# Returns the String.
-
1
def abf_worker_srcpath
-
file_name = "#{project.name}-#{commit_hash}"
-
opts = default_url_options
-
opts.merge!({user: user.authentication_token, password: ''}) if user.present?
-
url_helpers.archive_url(
-
project.name_with_owner,
-
file_name,
-
'tar.gz',
-
opts
-
)
-
end
-
-
# Private: Get params for ABF worker task.
-
#
-
# Returns the String with space separated params.
-
1
def abf_worker_params
-
p = {
-
'BUILD_ID' => id,
-
'PROJECT' => project.name_with_owner,
-
'PROJECT_VERSION' => project_version,
-
'COMMIT_HASH' => commit_hash,
-
}
-
if product.platform.hidden?
-
token = product.platform.tokens.by_active.where(description: CACHED_CHROOT_TOKEN_DESCRIPTION).first
-
p.merge!('TOKEN' => token.authentication_token) if token
-
end
-
p.map{ |k, v| "#{k}=#{v}" } * ' ' + ' ' + params.to_s
-
end
-
-
end
-
# Internal: various definitions and instance methods related to status.
-
#
-
# This module gets mixed in into ProductBuildList class.
-
1
module ProductBuildLists::Statusable
-
1
extend ActiveSupport::Concern
-
-
1
BUILD_COMPLETED = 0
-
1
BUILD_FAILED = 1
-
1
BUILD_PENDING = 2
-
1
BUILD_STARTED = 3
-
1
BUILD_CANCELED = 4
-
1
BUILD_CANCELING = 5
-
1
BUILD_COMPLETED_PARTIALLY = 6
-
-
STATUSES = [
-
1
BUILD_STARTED,
-
BUILD_COMPLETED,
-
BUILD_COMPLETED_PARTIALLY,
-
BUILD_FAILED,
-
BUILD_PENDING,
-
BUILD_CANCELED,
-
BUILD_CANCELING
-
].freeze
-
-
HUMAN_STATUSES = {
-
1
BUILD_STARTED => :build_started,
-
BUILD_COMPLETED => :build_completed,
-
BUILD_COMPLETED_PARTIALLY => :build_completed_partially,
-
BUILD_FAILED => :build_failed,
-
BUILD_PENDING => :build_pending,
-
BUILD_CANCELED => :build_canceled,
-
BUILD_CANCELING => :build_canceling
-
}.freeze
-
-
-
1
included do
-
-
1
scope :for_status, -> (status) { where(status: status) if status.present? }
-
-
1
validates :status,
-
presence: true,
-
inclusion: { in: STATUSES }
-
-
1
before_destroy :can_destroy?
-
-
1
state_machine :status, initial: :build_pending do
-
-
1
event :start_build do
-
1
transition build_pending: :build_started
-
end
-
-
1
event :cancel do
-
1
transition [:build_pending, :build_started] => :build_canceling
-
end
-
1
after_transition on: :cancel, do: :cancel_job
-
-
# build_canceling: :build_canceled - canceling from UI
-
# build_started: :build_canceled - canceling from worker by time-out (time_living has been expired)
-
1
event :build_canceled do
-
1
transition [:build_canceling, :build_started] => :build_canceled
-
end
-
-
# build_canceling: :build_completed - Worker hasn't time to cancel building because build had been already completed
-
1
event :build_success do
-
1
transition [:build_started, :build_canceling] => :build_completed
-
end
-
-
# build_canceling: :build_completed - Worker hasn't time to cancel building because build had been already completed
-
1
event :build_success_partially do
-
1
transition [:build_started, :build_canceling] => :build_completed_partially
-
end
-
-
# build_canceling: :build_failed - Worker hasn't time to cancel building because build had been already failed
-
1
event :build_error do
-
1
transition [:build_started, :build_canceling] => :build_failed
-
end
-
-
1
HUMAN_STATUSES.each do |code,name|
-
7
state name, value: code
-
end
-
end
-
-
end
-
-
1
module ClassMethods
-
1
def human_status(status)
-
I18n.t("layout.product_build_lists.statuses.#{HUMAN_STATUSES[status]}")
-
end
-
end
-
-
######################################
-
# Instance methods #
-
######################################
-
-
1
def build_started?
-
status == BUILD_STARTED
-
end
-
-
1
def build_canceling?
-
status == BUILD_CANCELING
-
end
-
-
1
def can_destroy?
-
[BUILD_STARTED, BUILD_PENDING, BUILD_CANCELING].exclude?(status)
-
end
-
-
1
def can_cancel?
-
[BUILD_STARTED, BUILD_PENDING].include?(status)
-
end
-
-
1
def human_status
-
self.class.human_status(status)
-
end
-
-
end
-
# Internal: various definitions and instance methods related to default_branch.
-
#
-
# This module gets mixed in into Project class.
-
1
module Project::DefaultBranch
-
1
extend ActiveSupport::Concern
-
-
1
include DefaultBranchable
-
-
1
included do
-
1
validate :check_default_branch
-
-
1
after_update :set_new_git_head
-
end
-
-
######################################
-
# Instance methods #
-
######################################
-
-
# Public: Get default branch according to owner configs.
-
#
-
# Returns found String branch name.
-
1
def resolve_default_branch
-
return default_branch unless owner.is_a?(Group) && owner.default_branch.present?
-
return default_branch unless repo.branches.map(&:name).include?(owner.default_branch)
-
return owner.default_branch unless default_branch.present?
-
default_branch == 'master' ? owner.default_branch : default_branch
-
end
-
-
# Public: Finds branch name for platforms.
-
#
-
# save_to_platform - The save Platform.
-
# build_for_platform - The build Platform.
-
#
-
# Returns found String branch name.
-
1
def project_version_for(save_to_platform, build_for_platform)
-
if repo.commits("#{save_to_platform.default_branch}").try(:first).try(:id)
-
save_to_platform.default_branch
-
elsif repo.commits("#{build_for_platform.default_branch}").try(:first).try(:id)
-
build_for_platform.default_branch
-
else
-
resolve_default_branch
-
end
-
end
-
-
# Public: Finds default head.
-
#
-
# treeish - The String treeish.
-
#
-
# Returns found String head.
-
1
def default_head(treeish = nil) # maybe need change 'head'?
-
# Attention!
-
# repo.commit(nil) => <Grit::Commit "b6c0f81deb17590d22fc07ba0bbd4aa700256f61">
-
# repo.commit(nil.to_s) => nil
-
return treeish if treeish.present? && repo.commit(treeish).present?
-
if repo.branches_and_tags.map(&:name).include?(treeish || resolve_default_branch)
-
treeish || resolve_default_branch
-
else
-
repo.branches_and_tags[0].try(:name) || resolve_default_branch
-
end
-
end
-
-
1
protected
-
-
# Private: Set git head.
-
1
def set_new_git_head
-
if saved_change_to_default_branch? && repo.branches.map(&:name).include?(default_branch)
-
repo.git.send(:'symbolic-ref', {}, 'HEAD', "refs/heads/#{default_branch}")
-
Project.project_aliases(self).update_all default_branch: default_branch
-
end
-
end
-
-
# Private: Validation for checking that the default branch is exist.
-
1
def check_default_branch
-
3
if self.repo.branches.count > 0 && self.repo.branches.map(&:name).exclude?(self.default_branch)
-
errors.add :default_branch, I18n.t('activerecord.errors.project.default_branch')
-
end
-
end
-
-
end
-
# Private: Finders of all sorts: methods to find Project records, methods to find
-
# other records which belong to given Project.
-
#
-
# This module gets included into Project.
-
1
module Project::Finders
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
-
1
scope :recent, -> { order(:name) }
-
1
scope :search_order, -> { order('CHAR_LENGTH(projects.name) ASC') }
-
1
scope :search_like, ->(q) {
-
q = q.to_s.strip
-
by_name("%#{q}%").search_order if q.present?
-
}
-
7
scope :by_name, ->(name) { where('projects.name ILIKE ?', name) if name.present? }
-
1
scope :by_owner, ->(name) { where('projects.owner_uname ILIKE ?', "%#{name}%") if name.present? }
-
-
1
scope :by_owner_and_name, ->(*params) {
-
term = params.map(&:strip).join('/').downcase
-
where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") if term.present?
-
}
-
1
scope :by_visibilities, ->(v) { where(visibility: v) }
-
1
scope :opened, -> { where(visibility: 'open') }
-
1
scope :package, -> { where(is_package: true) }
-
1
scope :addable_to_repository, ->(repository_id) {
-
where('projects.id NOT IN (
-
SELECT ptr.project_id
-
FROM project_to_repositories AS ptr
-
WHERE ptr.repository_id = ?)', repository_id)
-
}
-
1
scope :by_owners, ->(group_owner_ids, user_owner_ids) {
-
where("(projects.owner_id in (?) AND projects.owner_type = 'Group') OR
-
(projects.owner_id in (?) AND projects.owner_type = 'User')", group_owner_ids, user_owner_ids)
-
}
-
-
1
scope :project_aliases, ->(project) {
-
where.not(id: project.id).
-
where('alias_from_id IN (:ids) OR id IN (:ids)', { ids: [project.alias_from_id, project.id].compact })
-
}
-
-
1
after_commit :clear_caches
-
1
after_touch :clear_caches
-
end
-
-
1
module ClassMethods
-
-
# Public: Get cached Project record by owner and name.
-
#
-
# Returns Project record.
-
# Raises ActiveRecord::RecordNotFound if nothing was found.
-
1
def find_by_owner_and_name(first, last = nil)
-
1
arr = first.try(:split, '/') || []
-
1
arr = (arr << last).compact
-
1
return nil if arr.length != 2
-
1
find_by(owner_uname: arr.first, name: arr.last) || by_owner_and_name(*arr).first
-
# Rails.cache.fetch(['Project.find_by_owner_and_name', arr.first, arr.last]) do
-
# end || by_owner_and_name(*arr).first
-
end
-
-
1
def find_by_owner_and_name!(first, last = nil)
-
1
find_by_owner_and_name(first, last) or raise ActiveRecord::RecordNotFound
-
end
-
end
-
-
1
protected
-
-
# Private: after_commit and after_touch hook which clears find_cached cache.
-
1
def clear_caches
-
3
Rails.cache.delete(['Project.find_by_owner_and_name', owner_uname, name])
-
end
-
end
-
1
module RegenerationStatus
-
1
extend ActiveSupport::Concern
-
-
1
READY = 0
-
1
WAITING_FOR_REGENERATION = 100
-
1
REGENERATING = 200
-
-
HUMAN_STATUSES = {
-
1
READY => :ready,
-
WAITING_FOR_REGENERATION => :waiting_for_regeneration,
-
REGENERATING => :regenerating
-
}
-
-
HUMAN_REGENERATION_STATUSES = {
-
1
AbfWorker::BaseObserver::COMPLETED => :completed,
-
AbfWorker::BaseObserver::FAILED => :failed,
-
AbfWorker::BaseObserver::CANCELED => :canceled
-
}.freeze
-
-
1
included do
-
2
after_update :cleanup_file_store
-
-
2
def sha1_of_file_store_files
-
files = []
-
files << last_regenerated_log_sha1 if last_regenerated_log_sha1.present?
-
files
-
end
-
-
2
def human_regeneration_status
-
self.class::HUMAN_REGENERATION_STATUSES[last_regenerated_status] || :no_data
-
end
-
-
2
def human_status
-
self.class::HUMAN_STATUSES[status] || :no_data
-
end
-
-
2
def cleanup_file_store
-
12
old_log_sha1 = last_regenerated_log_sha1_was
-
12
if old_log_sha1.present? && old_log_sha1 != last_regenerated_log_sha1
-
later_destroy_files_from_file_store([old_log_sha1])
-
end
-
end
-
end
-
end
-
1
module TimeLiving
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
-
3
validates :time_living, numericality: { only_integer: true }, presence: true
-
-
3
validate -> {
-
# MIN_TIME_LIVING <= time_living <= MAX_TIME_LIVING or
-
# 2 min <= time_living <= 12 hours
-
# time_living in seconds
-
min = self.class.const_defined?(:MIN_TIME_LIVING) ? self.class::MIN_TIME_LIVING : 120
-
max = self.class.const_defined?(:MAX_TIME_LIVING) ? self.class::MAX_TIME_LIVING : 43200
-
if min > time_living.to_i || time_living.to_i > max
-
errors.add :time_living,
-
I18n.t('flash.time_living.numericality_error', min: (min / 60), max: (max / 60))
-
end
-
}
-
-
3
before_validation :convert_time_living
-
end
-
-
1
protected
-
-
1
def convert_time_living
-
self.time_living = time_living.to_i * 60 if time_living_was.to_i != time_living.to_i
-
end
-
end
-
1
module TokenAuthenticatable
-
1
extend ActiveSupport::Concern
-
-
1
module ClassMethods
-
1
def find_by_authentication_token(authentication_token = nil)
-
if authentication_token
-
where(authentication_token: authentication_token).first
-
end
-
end
-
end
-
-
1
def ensure_authentication_token
-
12
if authentication_token.blank?
-
12
self.authentication_token = generate_authentication_token
-
end
-
end
-
-
1
def reset_authentication_token!
-
self.authentication_token = generate_authentication_token
-
save
-
end
-
-
1
private
-
-
1
def generate_authentication_token
-
12
loop do
-
12
token = Devise.friendly_token
-
12
break token unless self.class.unscoped.where(authentication_token: token).first
-
end
-
end
-
end
-
1
module UrlHelper
-
1
def default_url_options
-
host ||= EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host]
-
protocol ||= APP_CONFIG['mailer_https_url'] ? 'https' : 'http' rescue 'http'
-
{ host: host, protocol: protocol }
-
end
-
end
-
1
module WebHooks
-
-
1
class << self
-
1
protected
-
-
1
def add_hook(name)
-
3
NAMES << name.to_s
-
3
@schema = []
-
3
yield if block_given?
-
3
SCHEMA[name] = @schema
-
3
@schema = []
-
end
-
-
1
def add_to_schema(type, attrs)
-
5
attrs.each do |attr|
-
13
@schema << [type, attr.to_sym]
-
end
-
end
-
-
1
def boolean(*attrs)
-
1
add_to_schema :boolean, attrs
-
end
-
-
1
def string(*attrs)
-
3
add_to_schema :string, attrs
-
end
-
-
1
def password(*attrs)
-
1
add_to_schema :password, attrs
-
end
-
end
-
-
1
NAMES = []
-
1
SCHEMA = {}
-
1
add_hook :web do
-
1
string :url
-
end
-
# temporarily disabled
-
# add_hook :hipchat do
-
# string :auth_token, :room, :restrict_to_branch
-
# boolean :notify
-
# end
-
1
add_hook :irc do
-
1
string :server, :port, :room, :nick, :branch_regexes
-
1
password :password
-
1
boolean :ssl, :message_without_join, :no_colors, :long_url, :notice
-
end
-
-
1
add_hook :jabber do
-
1
string :user
-
end
-
-
1
SCHEMA.freeze
-
1
NAMES.freeze
-
end
-
1
module Wiki
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
after_save :create_wiki
-
1
after_destroy :destroy_wiki
-
end
-
-
1
def wiki_path
-
build_path(wiki_repo_name)
-
end
-
-
1
def wiki_repo_name
-
File.join owner.uname, "#{name}.wiki"
-
end
-
-
1
protected
-
-
1
def create_wiki
-
3
if has_wiki && !FileTest.exist?(wiki_path)
-
Grit::Repo.init_bare(wiki_path)
-
wiki = Gollum::Wiki.new(wiki_path, { base_path: Rails.application.routes.url_helpers.project_wiki_index_path(self) })
-
wiki.write_page('Home', :markdown, I18n.t("wiki.seed.welcome_content"),
-
{ name: owner.name, email: owner.email, message: 'Initial commit' })
-
end
-
end
-
-
1
def destroy_wiki
-
FileUtils.rm_rf wiki_path
-
end
-
end
-
1
class EventLog < ActiveRecord::Base
-
1
belongs_to :user
-
1
belongs_to :eventable, polymorphic: true
-
-
# self.per_page = 1
-
-
1
scope :eager_loading, -> { preload(:user) }
-
1
scope :default_order, -> { order(id: :desc) }
-
-
1
before_create do
-
self.user_name = user.try(:uname) || 'guest'
-
self.eventable_name ||= eventable.name if eventable.respond_to?(:name)
-
end
-
# after_create { self.class.current_controller = nil }
-
-
1
class << self
-
1
def create_with_current_controller(attributes)
-
create(attributes) do |el|
-
el.user = current_controller.current_user
-
el.ip = current_controller.request.remote_ip
-
el.controller = current_controller.class.to_s
-
el.action = current_controller.action_name
-
el.protocol = 'web'
-
end
-
end
-
-
1
def current_controller
-
Thread.current[:current_controller]
-
end
-
-
1
def current_controller=(ctrl)
-
3
Thread.current[:current_controller] = ctrl
-
end
-
end
-
end
-
1
require 'digest/md5'
-
-
1
class FlashNotify < ActiveRecord::Base
-
1
include FlashNotify::Finders
-
-
1
STATUSES = %w[error success info]
-
-
1
validates :status, inclusion: {in: STATUSES}
-
1
validates :body_ru, :body_en, :status, presence: true
-
-
1
def hash_id
-
@digest ||= Digest::MD5.hexdigest("#{self.id}-#{self.updated_at}")
-
end
-
-
1
def body(language)
-
read_attribute("body_#{language}")
-
end
-
-
1
def should_show?(cookie_hash_id)
-
cookie_hash_id != hash_id && published
-
end
-
end
-
1
class GitHook
-
1
include Feed::Git
-
1
include Resque::Plugins::Status
-
-
1
ZERO = '0000000000000000000000000000000000000000'
-
1
@queue = :hook
-
-
1
attr_reader :repo, :newrev, :oldrev, :newrev_type, :oldrev_type, :refname,
-
:change_type, :rev, :rev_type, :refname_type, :owner, :project, :user, :message
-
-
1
def self.perform(*options)
-
self.process(*options)
-
end
-
-
1
def initialize(owner_uname, repo, newrev, oldrev, ref, newrev_type, user = nil, message = nil)
-
@repo, @newrev, @oldrev, @refname, @newrev_type, @user, @message = repo, newrev, oldrev, ref, newrev_type, user, message
-
if @owner = User.where(uname: owner_uname).first || Group.where(uname: owner_uname).first!
-
@project = @owner.own_projects.where(name: repo).first!
-
end
-
@change_type, @user = git_change_type, find_user(user)
-
git_revision_types
-
commit_type
-
end
-
-
1
def git_change_type
-
if oldrev == ZERO
-
return 'create'
-
elsif newrev == ZERO
-
return 'delete'
-
else
-
return 'update'
-
end
-
end
-
-
1
def git_revision_types
-
case change_type
-
when 'create', 'update'
-
@rev = newrev
-
when 'delete'
-
@rev = oldrev
-
end
-
@rev_type = newrev_type
-
end
-
-
1
def commit_type
-
if refname =~ /refs\/tags\/*/ && rev_type == 'commit'
-
# un-annotated tag
-
@refname_type= 'tag'
-
#~ short_refname=refname + '##refs/tags/'
-
elsif refname =~ /refs\/tags\/*/ && rev_type == 'tag'
-
# annotated tag
-
@refname_type="annotated tag"
-
#~ short_refname= refname + '##refs/tags/'
-
elsif refname =~ /refs\/heads\/*/ && rev_type == 'commit'
-
# branch
-
@refname_type= 'branch'
-
elsif refname =~ /refs\/remotes\/*'/ && rev_type == 'commit'
-
# tracking branch
-
@refname_type="tracking branch"
-
@short_refname= refname + '##refs/remotes/'
-
else
-
# Anything else (is there anything else?)
-
@refname_type= "*** Unknown type of update to $refname (#{rev_type})"
-
end
-
end
-
-
1
def self.process(*args)
-
Feed::Git.create_notifications(args.size > 1 ? GitHook.new(*args) : args.first)
-
end
-
-
1
def find_user(user)
-
if user.blank?
-
# Local push
-
User.find_by(email: project.repo.commit(newrev).author.email) rescue nil
-
elsif user =~ /\Auser-\d+\Z/
-
# git push over http
-
User.find(user.gsub('user-', ''))
-
elsif user =~ /\Akey-\d+\Z/
-
# git push over ssh
-
SshKey.find(user.gsub('key-', '')).try(:user)
-
end
-
end
-
end
-
1
class Group < Avatar
-
1
include ActsLikeMember
-
1
include PersonalRepository
-
1
include DefaultBranchable
-
-
1
belongs_to :owner, class_name: 'User'
-
-
1
has_many :relations, as: :actor, dependent: :destroy
-
1
has_many :actors, as: :target, class_name: 'Relation', dependent: :destroy
-
1
has_many :targets, as: :actor, class_name: 'Relation', dependent: :destroy
-
-
1
has_many :members, through: :actors, source: :actor, source_type: 'User', autosave: true
-
1
has_many :projects, through: :targets, source: :target, source_type: 'Project', autosave: true
-
-
1
has_many :own_projects, as: :owner, class_name: 'Project', dependent: :destroy
-
1
has_many :own_platforms, as: :owner, class_name: 'Platform', dependent: :destroy
-
-
1
validates :owner, presence: true
-
1
validates :uname, presence: true,
-
uniqueness: {case_sensitive: false},
-
format: {with: /\A[a-z0-9_]+\z/},
-
reserved_name: true,
-
length: { maximum: 100 }
-
1
validate { errors.add(:uname, :taken) if User.by_uname(uname).present? }
-
-
1
scope :opened, -> { all }
-
1
scope :by_owner, ->(owner) { where(owner_id: owner.id) }
-
1
scope :by_admin, ->(admin) {
-
joins(:actors).where('relations.role' => 'admin', 'relations.actor_id' => admin.id, 'relations.actor_type' => 'User')
-
}
-
1
scope :by_admin_and_writer, ->(actor) {
-
joins(:actors).where('relations.role' => ['admin', 'writer'], 'relations.actor_id' => actor.id, 'relations.actor_type' => 'User')
-
}
-
-
1
attr_readonly :uname
-
-
1
attr_accessor :delete_avatar
-
-
1
delegate :email, :user_appeal, to: :owner
-
-
1
after_create :add_owner_to_members
-
-
1
def self.can_own_project(user)
-
(by_owner(user) | by_admin_and_writer(user))
-
end
-
-
1
def name
-
uname
-
end
-
-
1
def add_member(member, role = 'admin')
-
Relation.add_member(member, self, role, :actors)
-
end
-
-
1
def remove_member(member)
-
Relation.remove_member(member, self)
-
end
-
-
1
def system?
-
false
-
end
-
-
1
def fullname
-
return description.present? ? "#{uname} (#{description})" : uname
-
end
-
-
1
protected
-
-
1
def add_owner_to_members
-
Relation.create_with_role(self.owner, self, 'admin') # members << self.owner if !members.exists?(id: self.owner.id)
-
end
-
end
-
1
class Hook < ActiveRecord::Base
-
1
include WebHooks
-
1
include UrlHelper
-
1
include Rails.application.routes.url_helpers
-
-
1
belongs_to :project
-
-
1
before_validation :cleanup_data
-
1
validates :project, :data, presence: true
-
1
validates :name, presence: true, inclusion: {in: NAMES}
-
-
1
serialize :data, Hash
-
-
1
scope :for_name, ->(name) { where(name: name) if name.present? }
-
-
1
def receive_issues(issue, action)
-
pull = issue.pull_request
-
return if action.to_sym == :create && pull
-
default_url_options
-
-
payload = meta(issue.project, issue.user)
-
base_params = {
-
number: issue.serial_id,
-
state: issue.status,
-
title: issue.title,
-
body: issue.body,
-
user: {login: issue.user.uname},
-
}
-
if pull
-
total_commits = pull.repo.commits_between(pull.to_commit, pull.from_commit).count
-
repo_owner = pull.to_project.owner.uname
-
post 'pull_request', {
-
payload: payload.merge(
-
action: (pull.ready? ? 'opened' : pull.status),
-
pull_request: base_params.merge(
-
commits: total_commits,
-
head: {label: "#{pull.from_project.owner.uname}:#{pull.from_ref}"},
-
base: {label: "#{repo_owner}:#{pull.to_ref}"},
-
html_url: project_pull_request_url(pull.to_project, pull)
-
)
-
).to_json
-
}
-
else
-
post 'issues', {
-
payload: payload.merge(
-
action: (issue.closed? ? 'closed' : 'opened'),
-
issue: base_params.merge(
-
html_url: project_issue_url(issue.project, issue)
-
)
-
).to_json
-
}
-
end
-
end
-
1
later :receive_issues, queue: :notification
-
-
1
def receive_push(git_hook)
-
default_url_options
-
project = Project.find(git_hook['project']['id'])
-
user = User.find(git_hook['user']['id'])
-
payload = meta(project, user)
-
oldrev, newrev, change_type = git_hook.values_at *%w(oldrev newrev change_type)
-
-
commits = []
-
payload.merge!(before: oldrev, after: newrev)
-
if %w(delete create).exclude? change_type
-
payload.merge!(
-
:compare => diff_url(project, "#{oldrev[0..6]}...#{newrev[0..6]}")
-
)
-
if oldrev == newrev
-
commits = [project.repo.commit(newrev)]
-
modified = commits.first.stats.files.map{|f| f[0]}
-
else
-
commits = project.repo.commits_between(oldrev, newrev)
-
end
-
end
-
-
post 'push', {
-
payload: payload.merge(
-
ref: git_hook['refname'],
-
commits: commits.map{ |commit|
-
files = changed_files commit
-
{
-
id: commit.id,
-
message: commit.message,
-
distinct: true,
-
url: commit_url(project, commit),
-
removed: files[:removed],
-
added: files[:added],
-
modified: files[:modified],
-
timestamp: commit.committed_date,
-
author: {name: commit.committer.name, email: commit.committer.email}
-
}
-
}
-
).to_json
-
}
-
end
-
1
later :receive_push, queue: :notification
-
-
1
protected
-
-
1
def post(action, params)
-
github_services = APP_CONFIG['github_services']
-
uri = URI "http://#{github_services['ip']}:#{github_services['port']}/#{name}/#{action}"
-
Net::HTTP.post_form uri, params.merge(data: data.to_json)
-
rescue # Dont care about it
-
end
-
-
1
def meta(project, user)
-
{
-
repository: {
-
name: project.name,
-
url: project_url(project),
-
owner: { login: project.owner.uname }
-
},
-
sender: {login: user.uname},
-
pusher: {name: user.uname}
-
}
-
end
-
-
1
def cleanup_data
-
if self.name.present? && fields = SCHEMA[self.name.to_sym]
-
new_data = {}
-
fields.each { |type, field| new_data[field] = self.data[field] }
-
self.data = new_data
-
end
-
end
-
-
1
def changed_files(commit)
-
removed, added, modified = [], [], []
-
commit.show.each do |diff|
-
if diff.renamed_file
-
added << diff.b_path
-
removed << diff.a_path
-
elsif diff.new_file
-
added << diff.b_path
-
elsif diff.deleted_file
-
removed << diff.a_path
-
else
-
modified << diff.a_path
-
end
-
end
-
{ removed: removed, added: added, modified: modified }
-
end
-
-
end
-
1
class Invite < ActiveRecord::Base
-
1
TTL = 3.days
-
1
MAX_UNUSED_INVITES = 5
-
-
1
belongs_to :user
-
1
belongs_to :invited_user, class_name: 'User'
-
-
1
before_create :generate_invite_key
-
-
1
scope :owned, ->(u) { where(user_id: u.try(:id) || u) }
-
1
scope :unused, ->() { where(invited_user_id: nil) }
-
1
scope :outdated, ->() { where('created_at <= ? AND invited_user_id IS NULL', TTL.ago) }
-
-
1
validate :max_count_exceeded
-
-
1
def used?
-
!invited_user.nil?
-
end
-
-
1
def unused?
-
invited_user.nil?
-
end
-
-
1
def remaining_ttl
-
ret = TTL - (Time.now.utc - created_at)
-
return 0 if ret < 0
-
ret
-
end
-
-
1
private
-
-
1
def generate_invite_key
-
self.invite_key = SecureRandom.hex(20)
-
end
-
-
1
def max_count_exceeded
-
if !persisted? && user_id.present? && Invite.owned(user_id).unused.count >= 5
-
errors.add(
-
:base,
-
I18n.t('flash.invite.max_limit_exceeded', number: MAX_UNUSED_INVITES)
-
)
-
end
-
end
-
end
-
1
class Issue < ActiveRecord::Base
-
1
include Feed::Issue
-
-
STATUSES = [
-
1
STATUS_OPEN = 'open',
-
STATUS_REOPEN = 'reopen',
-
STATUS_CLOSED = 'closed'
-
]
-
1
HASH_TAG_REGEXP = /([a-zA-Z0-9\-_]*\/)?([a-zA-Z0-9\-_]*)?#([0-9]+)/
-
1
self.per_page = 20
-
-
1
belongs_to :project
-
1
belongs_to :user
-
1
belongs_to :assignee,
-
class_name: 'User',
-
foreign_key: 'assignee_id',
-
optional: true
-
-
1
belongs_to :closer,
-
class_name: 'User',
-
foreign_key: 'closed_by',
-
optional: true
-
-
1
has_many :comments,
-
as: :commentable,
-
dependent: :destroy
-
-
1
has_many :subscribes,
-
as: :subscribeable,
-
dependent: :destroy
-
-
1
has_many :labelings,
-
dependent: :destroy
-
-
1
has_many :labels,
-
-> { distinct },
-
through: :labelings
-
-
1
has_one :pull_request#, dependent: :destroy
-
-
1
validates :title, :body, :project, presence: true
-
1
validates :title, length: { maximum: 100 }
-
1
validates :body, length: { maximum: 10000 }
-
-
1
after_create :set_serial_id
-
1
after_create :subscribe_users
-
1
after_update :subscribe_issue_assigned_user
-
-
1
before_create :update_statistic
-
1
before_update :update_statistic
-
-
1
accepts_nested_attributes_for :labelings,
-
reject_if: -> (attributes) { attributes['label_id'].blank? },
-
allow_destroy: true
-
-
1
scope :opened, -> { where(status: [STATUS_OPEN, STATUS_REOPEN]) }
-
1
scope :closed, -> { where(status: STATUS_CLOSED) }
-
-
3
scope :needed_checking, -> { where(issues: { status: %w(open reopen blocked ready already) }) }
-
3
scope :not_closed_or_merged, -> { needed_checking }
-
1
scope :closed_or_merged, -> { where(issues: { status: %w(closed merged) }) }
-
# Using mb_chars for correct transform to lowercase ('Русский Текст'.downcase => "Русский Текст")
-
1
scope :search_like, ->(q) {
-
where("#{table_name}.title ILIKE ?", "%#{q.mb_chars.downcase}%") if q.present?
-
}
-
1
scope :without_pull_requests, -> {
-
1
where('NOT EXISTS (select null from pull_requests as pr where pr.issue_id = issues.id)').
-
references(:pull_requests)
-
}
-
-
1
attr_accessor :new_pull_request
-
-
1
def assign_uname
-
assignee.uname if assignee
-
end
-
-
1
def to_param
-
serial_id.to_s
-
end
-
-
1
def subscribe_creator(creator_id)
-
unless self.subscribes.exists?(user_id: creator_id)
-
self.subscribes.create(user_id: creator_id)
-
end
-
end
-
-
1
def closed?
-
closed_by && closed_at && status == STATUS_CLOSED
-
end
-
-
1
def set_close(closed_by)
-
self.closed_at = Time.now.utc
-
self.closer = closed_by
-
self.status = STATUS_CLOSED
-
end
-
-
1
def set_open
-
self.closed_at = self.closed_by = nil
-
self.status = STATUS_REOPEN
-
end
-
-
1
def collect_recipients
-
recipients = self.project.all_members
-
recipients = recipients | [self.assignee] if self.assignee
-
recipients
-
end
-
-
1
def self.find_by_hash_tag(hash_tag, current_user, project)
-
hash_tag =~ HASH_TAG_REGEXP
-
owner_uname = Regexp.last_match[1].presence || Regexp.last_match[2].presence || project.owner.uname
-
project_name = Regexp.last_match[1] ? Regexp.last_match[2] : project.name
-
serial_id = Regexp.last_match[3]
-
project = Project.find_by_owner_and_name(owner_uname.chomp('/'), project_name)
-
return nil unless project
-
return nil unless ProjectPolicy.new(current_user, project).show?
-
project.issues.where(serial_id: serial_id).first
-
end
-
-
1
protected
-
-
1
def update_statistic
-
key = (pull_request || new_pull_request) ? Statistic::KEY_PULL_REQUEST : Statistic::KEY_ISSUE
-
Statistic.statsd_increment(
-
activity_at: Time.now,
-
key: "#{key}.#{status}",
-
project_id: project_id,
-
user_id: closed_by || user_id,
-
) if new_record? || status_changed?
-
end
-
-
1
def set_serial_id
-
self.serial_id = self.project.issues.maximum(:serial_id).to_i+1
-
self.save!
-
end
-
-
1
def subscribe_users
-
collect_recipients.each do |recipient|
-
if recipient.notifier.new_comment && !self.subscribes.exists?(user_id: recipient.id)
-
ss = self.subscribes.create(user_id: recipient.id)
-
end
-
end
-
end
-
-
1
def subscribe_issue_assigned_user
-
if self.assignee_id && saved_change_to_attribute?(:assignee_id)
-
was_assignee_id = saved_change_to_attribute(:assignee_id)
-
self.subscribes.where(user_id: was_assignee_id).first.try(:destroy) unless was_assignee_id.blank?
-
if self.assignee.notifier.issue_assign && !self.subscribes.exists?(user_id: self.assignee_id)
-
self.subscribes.create(user_id: self.assignee_id)
-
end
-
end
-
end
-
end
-
1
require 'open3'
-
1
class KeyPair < ActiveRecord::Base
-
1
belongs_to :repository
-
1
belongs_to :user
-
-
1
attr_accessor :fingerprint
-
1
attr_encrypted :secret, key: APP_CONFIG['keys']['key_pair_secret_key']
-
-
1
validates :repository, :user, presence: true
-
1
validates :secret, :public, presence: true, length: { maximum: 10000 }, on: :create
-
-
1
validates :repository_id, uniqueness: { message: I18n.t("activerecord.errors.key_pair.repo_key_exists") }
-
1
validate :check_keys
-
-
1
before_create { |record| record.key_id = @fingerprint }
-
1
after_create { |record| record.repository.resign }
-
-
1
protected
-
-
1
def check_keys
-
dir = Dir.mktmpdir 'keys-', APP_CONFIG['tmpfs_path']
-
begin
-
%w(pubring secring).each do |kind|
-
filename = "#{dir}/#{kind}"
-
open("#{filename}.txt", "w") { |f| f.write self.send(kind == 'pubring' ? :public : :secret) }
-
system "gpg --homedir #{dir} --dearmor < #{filename}.txt > #{filename}.gpg"
-
end
-
-
public_key = get_info_of_key "#{dir}/pubring.txt"
-
secret_key = get_info_of_key "#{dir}/secring.txt"
-
-
if correct_key?(public_key, :public) & correct_key?(secret_key, :secret)
-
if public_key[:fingerprint] != secret_key[:fingerprint]
-
errors.add :secret, I18n.t('activerecord.errors.key_pair.wrong_keys')
-
else
-
stdin, stdout, stderr = Open3.popen3("echo '\n\n\n\n\nsave' | LC_ALL=en gpg --command-fd 0 --homedir #{dir} --edit-key #{secret_key[:keyid]} passwd")
-
output = stderr.read
-
if output =~ /Invalid\spassphrase/
-
errors.add :secret, I18n.t('activerecord.errors.key_pair.key_has_passphrase')
-
else
-
@fingerprint = secret_key[:fingerprint]
-
end
-
end
-
end
-
ensure
-
# remove the directory.
-
FileUtils.remove_entry_secure dir
-
end
-
end
-
-
1
def correct_key?(info, field)
-
if info.empty? || info[:type].blank? || info[:fingerprint].blank? || info[:keyid].blank?
-
errors.add field, I18n.t('activerecord.errors.key_pair.wrong_key')
-
return false
-
else
-
if info[:type] != field
-
errors.add field, I18n.t("activerecord.errors.key_pair.wrong_#{field}_key")
-
return false
-
end
-
end
-
return true
-
end
-
-
1
def get_info_of_key(file_path)
-
results = {}
-
str = %x[ cat #{file_path} | gpg --quiet --import-options import-show --dry-run --keyid-format LONG --import | sed -n 1,2p ]
-
info = str.strip.split("\n")
-
if info.size == 2
-
results[:fingerprint] = info[1].gsub(/.*\=/, '').strip.gsub(/\s/, ':')
-
-
results[:type] = info[0] =~ /^pub\s/ ? :public : nil
-
results[:type] ||= info[0] =~ /^sec#\s/ ? :secret : nil
-
-
if keyid = info[0].match(/\/[\w]+\s/)
-
results[:keyid] = keyid[0].strip[1..-1]
-
end
-
end
-
return results
-
end
-
-
end
-
1
class Label < ActiveRecord::Base
-
1
has_many :labelings, dependent: :destroy
-
1
has_many :issues, through: :labelings
-
1
belongs_to :project
-
-
1
validates :name, uniqueness: { scope: :project_id }
-
1
validates :name, length: { in: 1..20 }
-
-
1
validates :color, presence: true
-
1
validates :color, format: { with: /\A([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/, message: I18n.t('layout.issues.invalid_labels') }
-
end
-
1
class Labeling < ActiveRecord::Base
-
1
belongs_to :issue
-
1
belongs_to :label
-
end
-
1
class MassBuild < ActiveRecord::Base
-
1
include ExternalNodable
-
-
1
AUTO_PUBLISH_STATUSES = %w(none default testing)
-
-
1
STATUSES, HUMAN_STATUSES = [], {}
-
[
-
1
%w(SUCCESS 0),
-
%w(BUILD_STARTED 3000),
-
%w(BUILD_PENDING 2000),
-
].each do |kind, value|
-
3
value = value.to_i
-
3
const_set kind, value
-
3
STATUSES << value
-
3
HUMAN_STATUSES[value] = kind.downcase.to_sym
-
end
-
1
STATUSES.freeze
-
1
HUMAN_STATUSES.freeze
-
-
1
state_machine :status, initial: :build_pending do
-
1
event :start do
-
1
transition build_pending: :build_started
-
end
-
-
1
event :done do
-
1
transition build_started: :success
-
end
-
-
1
HUMAN_STATUSES.each do |code,name|
-
3
state name, value: code
-
end
-
end
-
-
1
belongs_to :build_for_platform, -> { where(platform_type: 'main') }, class_name: 'Platform'
-
1
belongs_to :save_to_platform, class_name: 'Platform'
-
1
belongs_to :user
-
1
has_many :build_lists, dependent: :destroy
-
-
1
serialize :extra_repositories, Array
-
1
serialize :extra_build_lists, Array
-
1
serialize :extra_mass_builds, Array
-
-
1
scope :recent, -> { order(created_at: :desc) }
-
1
scope :outdated, -> { where("#{table_name}.created_at < ?", Time.now + 1.day - BuildList::MAX_LIVE_TIME) }
-
1
scope :search_like, -> (q) { where("#{table_name}.description ILIKE ?", "%#{q}%") if q.present? }
-
-
1
attr_accessor :arches, :repositories
-
-
1
validates :save_to_platform_id,
-
:build_for_platform_id,
-
:arch_names,
-
:name,
-
:user_id,
-
presence: true
-
-
1
validates :projects_list,
-
presence: true,
-
length: { maximum: 500_000 }
-
-
1
validates :description,
-
length: { maximum: 255 }
-
-
1
validates :auto_publish_status,
-
inclusion: { in: AUTO_PUBLISH_STATUSES }
-
-
1
validates :increase_release_tag,
-
:use_cached_chroot,
-
:use_extra_tests,
-
inclusion: { in: [true, false] }
-
-
1
after_commit :build_all, on: :create, if: Proc.new { |mb| mb.extra_mass_builds.blank? }
-
1
before_validation :set_data, on: :create
-
-
1
COUNT_STATUSES = %i(
-
build_lists
-
build_published
-
build_pending
-
build_started
-
build_publish
-
build_error
-
success
-
build_canceled
-
)
-
-
1
def build_all
-
return unless start
-
# later with resque
-
arches_list = arch_names ? Arch.where(name: arch_names.split(', ')) : Arch.all
-
projects_list.lines.each do |name|
-
next if name.blank?
-
name.chomp!; name.strip!
-
-
if project = Project.joins(:repositories).where('repositories.id in (?)', save_to_platform.repository_ids).find_by(name: name)
-
begin
-
return if self.reload.stop_build
-
# Ensures that user has rights to create a build_list
-
next unless ProjectPolicy.new(user, project).write?
-
increase_rt = increase_release_tag?
-
arches_list.each do |arch|
-
rep_id = (project.repository_ids & save_to_platform.repository_ids).first
-
project.build_for(self, rep_id, arch, 0, increase_rt)
-
increase_rt = false
-
end
-
rescue RuntimeError, Exception
-
end
-
else
-
MassBuild.increment_counter :missed_projects_count, id
-
list = (missed_projects_list || '') << "#{name}\n"
-
update_column :missed_projects_list, list
-
end
-
end
-
done
-
end
-
1
later :build_all, queue: :low
-
-
1
def generate_failed_builds_list
-
generate_list BuildList::BUILD_ERROR
-
end
-
-
1
def generate_tests_failed_builds_list
-
generate_list BuildList::TESTS_FAILED
-
end
-
-
1
def generate_success_builds_list
-
generate_list BuildList::SUCCESS
-
end
-
-
1
def cancel_all
-
update_column(:stop_build, true)
-
build_lists.find_each(batch_size: 100) do |bl|
-
bl.cancel
-
end
-
end
-
1
later :cancel_all, queue: :low
-
-
1
def publish_success_builds(user)
-
publish user, BuildList::SUCCESS, BuildList::FAILED_PUBLISH
-
end
-
1
later :publish_success_builds, queue: :low
-
-
1
def publish_test_failed_builds(user)
-
publish user, BuildList::TESTS_FAILED
-
end
-
1
later :publish_test_failed_builds, queue: :low
-
-
1
COUNT_STATUSES.each do |stat|
-
8
stat_count = "#{stat}_count"
-
define_method stat_count do
-
Rails.cache.fetch([self, "cached_#{stat_count}"], expires_in: 5.minutes) do
-
build_lists.where(status: BuildList::HUMAN_STATUSES.key(stat)).count
-
end
-
8
end if stat != :build_lists
-
end
-
-
1
private
-
-
1
def generate_list(status)
-
report = ""
-
BuildList.select('build_lists.id, projects.name as project_name, arches.name as arch_name').
-
where(
-
status: status,
-
mass_build_id: self.id
-
).joins(:project, :arch).find_each(batch_size: 100) do |build_list|
-
report << "ID: #{build_list.id}; "
-
report << "PROJECT_NAME: #{build_list.project_name}; "
-
report << "ARCH: #{build_list.arch_name}\n"
-
end
-
report
-
end
-
-
1
def publish(user, *statuses)
-
builds = build_lists.where(status: statuses)
-
builds.update_all(publisher_id: user.id)
-
builds.find_each(batch_size: 50) do |bl|
-
bl.now_publish if bl.can_publish? && bl.has_new_packages?
-
end
-
end
-
-
1
def set_data
-
if save_to_platform
-
self.name = "#{Time.now.utc.to_date.strftime("%d.%b")}-#{save_to_platform.name}"
-
self.build_for_platform = save_to_platform if save_to_platform.main?
-
end
-
self.arch_names = Arch.where(id: arches).map(&:name).join(", ")
-
-
self.projects_list = projects_list.lines.map do |name|
-
name.chomp.strip if name.present?
-
end.compact.uniq.join("\r\n") if projects_list.present?
-
end
-
end
-
1
class Platform < ActiveRecord::Base
-
1
extend FriendlyId
-
1
friendly_id :name, use: [:finders]
-
-
1
include FileStoreClean
-
1
include RegenerationStatus
-
1
include Owner
-
1
include EventLoggable
-
1
include EmptyMetadata
-
1
include DefaultBranchable
-
1
include Platform::Finders
-
-
1
self.per_page = 20
-
-
1
CACHED_CHROOT_PRODUCT_NAME = 'cached-chroot'
-
1
AUTOMATIC_METADATA_REGENERATIONS = %w(day week)
-
VISIBILITIES = [
-
1
VISIBILITY_OPEN = 'open',
-
VISIBILITY_HIDDEN = 'hidden'
-
]
-
1
NAME_PATTERN = /[\w\-\.]+/
-
1
HUMAN_STATUSES = HUMAN_STATUSES.clone.freeze
-
TYPES = [
-
1
TYPE_PERSONAL = 'personal',
-
TYPE_MAIN = 'main'
-
]
-
-
1
belongs_to :parent, class_name: 'Platform', foreign_key: 'parent_platform_id', optional: true
-
1
belongs_to :owner, polymorphic: true
-
-
1
has_many :repositories, dependent: :destroy
-
1
has_many :key_pairs, through: :repositories
-
1
has_many :projects, through: :repositories
-
-
1
has_many :products, dependent: :destroy
-
1
has_many :tokens, as: :subject, dependent: :destroy
-
1
has_many :platform_arch_settings, dependent: :destroy
-
1
has_many :repository_statuses
-
-
1
has_many :relations, as: :target, dependent: :destroy
-
1
has_many :actors, as: :target, class_name: 'Relation', dependent: :destroy
-
1
has_many :members, through: :actors, source: :actor, source_type: 'User'
-
-
-
1
has_and_belongs_to_many :advisories
-
-
1
has_many :packages, class_name: "BuildList::Package", dependent: :destroy
-
-
1
has_many :mass_builds, foreign_key: :save_to_platform_id
-
-
1
validates :description,
-
presence: true,
-
length: { maximum: 10000 }
-
-
1
validates :visibility,
-
presence: true,
-
inclusion: { in: VISIBILITIES }
-
-
1
validates :platform_type,
-
presence: true,
-
inclusion: { in: TYPES }
-
-
1
validates :automatic_metadata_regeneration,
-
inclusion: { in: AUTOMATIC_METADATA_REGENERATIONS },
-
allow_blank: true
-
-
1
validates :name,
-
uniqueness: { case_sensitive: false },
-
presence: true,
-
format: { with: /\A#{NAME_PATTERN}\z/ },
-
length: { maximum: 100 }
-
-
1
validates :default_branch,
-
presence: true
-
-
1
validates :distrib_type,
-
presence: true,
-
inclusion: { in: APP_CONFIG['distr_types'] }
-
-
1
validate -> {
-
30
if released_was && !released
-
errors.add(:released, I18n.t('flash.platform.released_status_can_not_be_changed'))
-
end
-
}
-
-
1
validate -> {
-
12
if personal? && (owner_id_changed? || owner_type_changed?)
-
errors.add :owner, I18n.t('flash.platform.owner_can_not_be_changed')
-
end
-
}, on: :update
-
-
1
before_create :create_directory
-
1
before_destroy :detele_directory
-
-
1
after_update :freeze_platform_and_update_repos
-
1
after_update :update_owner_relation
-
-
19
after_commit -> { symlink_directory unless hidden? }, on: :create
-
1
after_destroy -> { remove_symlink_directory unless hidden? }
-
-
1
accepts_nested_attributes_for :platform_arch_settings, allow_destroy: true
-
-
1
attr_accessor :admin_id, :term
-
-
1
attr_readonly :name, :distrib_type, :parent_platform_id, :platform_type
-
-
1
state_machine :status, initial: :ready do
-
-
1
after_transition on: :ready, do: :notify_users
-
-
1
event :ready do
-
1
transition regenerating: :ready
-
end
-
-
1
event :regenerate do
-
1
transition ready: :waiting_for_regeneration, if: ->(p) { p.main? }
-
end
-
-
1
event :start_regeneration do
-
1
transition waiting_for_regeneration: :regenerating
-
end
-
-
1
HUMAN_STATUSES.each do |code,name|
-
3
state name, value: code
-
end
-
end
-
-
1
def clear
-
system("rm -Rf #{ APP_CONFIG['root_path'] }/platforms/#{ self.name }/repository/*")
-
end
-
-
1
def urpmi_list(host = nil, pair = nil, add_commands = true, repository_name = 'main')
-
host ||= default_host
-
urpmi_commands = ActiveSupport::OrderedHash.new
-
-
# TODO: rename method or create separate methods for mdv and rhel
-
# Platform.main.opened.where(distrib_type: APP_CONFIG['distr_types'].first).each do |pl|
-
arches = Arch.all.to_a
-
Platform.main.opened.each do |pl|
-
urpmi_commands[pl.name] = {}
-
# FIXME should support restricting access to the hidden platform
-
arches.each do |arch|
-
tail = "/#{arch.name}/#{repository_name}/release"
-
command = add_commands ? "urpmi.addmedia #{name} " : ''
-
command << "#{APP_CONFIG['downloads_url']}/#{name}/repository/#{pl.name}#{tail}"
-
urpmi_commands[pl.name][arch.name] = command
-
end
-
end
-
-
return urpmi_commands
-
end
-
-
1
def path
-
build_path(name)
-
end
-
-
1
def add_member(member, role = 'admin')
-
Relation.add_member(member, self, role)
-
end
-
-
1
def remove_member(member)
-
Relation.remove_member(member, self)
-
end
-
-
1
def symlink_path
-
Rails.root.join("public", "downloads", name)
-
end
-
-
# Returns URL to repository, for example:
-
# - http://abf-downloads.rosalinux.ru/rosa-server2012/repository/x86_64/base/
-
# - http://abf-downloads.rosalinux.ru/uname_personal/repository/rosa-server2012/x86_64/base/
-
1
def public_downloads_url(subplatform_name = nil, arch = nil, repo = nil)
-
"#{APP_CONFIG['downloads_url']}/#{name}/repository/".tap do |url|
-
url << "#{subplatform_name}/" if subplatform_name.present?
-
url << "#{arch}/" if arch.present?
-
url << "#{repo}/" if repo.present?
-
end
-
end
-
-
1
def hidden?
-
20
visibility == VISIBILITY_HIDDEN
-
end
-
-
1
def personal?
-
12
platform_type == TYPE_PERSONAL
-
end
-
-
1
def main?
-
15
platform_type == TYPE_MAIN
-
end
-
-
1
def base_clone(attrs = {}) # :description, :name, :owner
-
dup.tap do |c|
-
attrs.each {|k,v| c.send("#{k}=", v)} # c.attributes = attrs
-
c.updated_at = nil; c.created_at = nil
-
c.parent = self; c.released = false
-
end
-
end
-
-
1
def clone_relations(from = parent)
-
self.repositories = from.repositories.map{|r| r.full_clone(platform_id: id)}
-
self.products = from.products.map(&:full_clone)
-
end
-
-
1
def full_clone(attrs = {})
-
base_clone(attrs).tap do |c|
-
with_skip {c.save} and c.clone_relations(self) and c.fs_clone # later with resque
-
end
-
end
-
-
1
def change_visibility
-
if hidden?
-
update(visibility: VISIBILITY_OPEN)
-
else
-
update(visibility: VISIBILITY_HIDDEN)
-
end
-
end
-
-
1
def symlink_directory
-
# umount_directory_for_rsync # TODO ignore errors
-
system("ln -s #{path} #{symlink_path}")
-
Arch.all.each do |arch|
-
str = "country=Russian Federation,city=Moscow,latitude=52.18,longitude=48.88,bw=1GB,version=2011,arch=#{arch.name},type=distrib,url=#{public_downloads_url}\n"
-
File.open(File.join(symlink_path, "#{name}.#{arch.name}.list"), 'w') {|f| f.write(str) }
-
end
-
end
-
1
later :symlink_directory, queue: :middle
-
-
1
def remove_symlink_directory
-
system("rm -Rf #{symlink_path}")
-
end
-
-
1
def update_owner_relation
-
12
if owner_id_was != owner_id
-
r = relations.where(actor_id: owner_id_was, actor_type: owner_type_was).first
-
r.update(actor_id: owner_id, actor_type: owner_type)
-
end
-
end
-
-
1
def destroy
-
with_skip {super} # avoid cascade XML RPC requests
-
end
-
1
later :destroy, queue: :low
-
-
1
def default_host
-
EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host]
-
end
-
-
# Checks access rights to platform and caching for 1 day.
-
1
def self.allowed?(path, token)
-
platform_name = path.gsub(/^[\/]+/, '')
-
.match(/^(#{NAME_PATTERN}\/|#{NAME_PATTERN}$)/)
-
-
return true unless platform_name
-
platform_name = platform_name[0].gsub(/\//, '')
-
-
Rails.cache.fetch([platform_name, token, :platform_allowed], expires_in: 2.minutes) do
-
platform = Platform.find_by name: platform_name
-
next false unless platform
-
next true unless platform.hidden?
-
return false if token.blank?
-
return true if platform.tokens.by_active.where(authentication_token: token).exists?
-
user = User.find_by(authentication_token: token)
-
!!(user && PlatformPolicy.new(user, platform).show?)
-
end
-
end
-
-
1
def cached_chroot(arch)
-
return false if personal?
-
Rails.cache.fetch([:cached_chroot, name, arch], expires_in: 10.minutes) do
-
product = products.where(name: CACHED_CHROOT_PRODUCT_NAME).first
-
next false unless product
-
pbl = product.product_build_lists.for_status(ProductBuildList::BUILD_COMPLETED).recent.first
-
next false unless pbl
-
result = pbl.results.find{ |r| r['file_name'] =~ /-#{arch}.tar.gz$/ }
-
result.present? ? result['sha1'] : false
-
end
-
end
-
-
1
def self.autostart_metadata_regeneration(value)
-
Platform.main.where(automatic_metadata_regeneration: value).each(&:regenerate)
-
end
-
-
1
def self.availables_main_platforms(user)
-
p_ids = Rails.cache.fetch([:availables_main_platforms, user], expires_in: 10.minutes) do
-
PlatformPolicy::Scope.new(user, Platform).show.main.joins(:repositories).
-
where('repositories.id IS NOT NULL').uniq.pluck(:id)
-
end
-
Platform.preload(:repositories).where(id: p_ids).order(:name)
-
end
-
-
1
protected
-
-
1
def create_directory
-
18
system("mkdir -p -m 0777 #{build_path([name, 'repository'])}")
-
end
-
-
1
def build_path(dir)
-
18
File.join(APP_CONFIG['root_path'], 'platforms', dir)
-
end
-
-
1
def detele_directory
-
FileUtils.rm_rf path
-
end
-
-
1
def fs_clone(old_name = parent.name, new_name = name)
-
FileUtils.cp_r "#{parent.path}/repository", path
-
end
-
1
later :fs_clone, queue: :low
-
-
1
def freeze_platform_and_update_repos
-
12
if released_changed? && released == true
-
repositories.update_all(publish_without_qa: false)
-
end
-
end
-
-
1
def notify_users
-
users = members.includes(:notifier).select{ |u| u.notifier.can_notify? }
-
users.each{ |u| UserMailer.metadata_regeneration_notification(self, u).deliver }
-
end
-
-
end
-
1
class PlatformArchSetting < ActiveRecord::Base
-
1
DEFAULT_TIME_LIVING = 43200 # seconds, 12 hours
-
1
MIN_TIME_LIVING = 600 # seconds, 10 minutes
-
1
MAX_TIME_LIVING = 360000 # seconds, 100 hours, 4 day and 4 hours
-
1
include TimeLiving
-
-
1
belongs_to :arch
-
1
belongs_to :platform
-
-
1
validates :arch, :platform, presence: true
-
1
validates :platform_id, uniqueness: { scope: :arch_id }
-
1
validate lambda {
-
errors.add(:platform, I18n.t('flash.platform_arch_settings.wrong_platform')) unless platform.main?
-
}
-
-
1
scope :by_arch, ->(arch) { where(arch_id: arch) if arch.present? }
-
1
scope :by_default, -> { where(default: true) }
-
end
-
1
class PlatformContent
-
-
1
attr_reader :path
-
-
1
def initialize(platform, path)
-
@platform, @path = platform, path
-
end
-
-
1
def build_list
-
return @build_list if !!@build_list
-
return nil if @path !~ /\/(release|updates)+\/[\w\-\.\+]+$/
-
return nil unless repository_name = @path.match(/\/[\w]+\/(release|updates)\//)
-
repository_name = repository_name[0].gsub(/\/(release|updates)\/$/, '').gsub('/', '')
-
-
repository = @platform.repositories.where(name: repository_name).first
-
return nil unless repository
-
-
if @platform.main?
-
build_for_platform = @platform
-
else
-
bfp_name = @path.match(/\/#{@platform.name}\/repository\/[\w]+\//)
-
return nil unless bfp_name
-
bfp_name = bfp_name[0].gsub(/\/#{@platform.name}\/repository\//, '').gsub('/', '')
-
build_for_platform = Platform.main.find_by name: bfp_name
-
return nil unless build_for_platform
-
end
-
-
@build_list = BuildList.for_status(BuildList::BUILD_PUBLISHED)
-
.for_platform(build_for_platform)
-
.scoped_to_save_platform(@platform)
-
.where(save_to_repository_id: repository)
-
.where(build_list_packages: {fullname: name, actual: true})
-
.joins(:packages)
-
.last
-
-
return @build_list
-
end
-
-
1
def name
-
@name ||= @path.gsub(/.*#{File::SEPARATOR}/, '')
-
end
-
-
1
def size
-
@size ||= File.size(@path) rescue nil
-
end
-
-
1
def is_folder?
-
@is_folder.nil? ? (@is_folder = File.directory?(@path)) : @is_folder
-
end
-
-
1
def download_url
-
"#{APP_CONFIG['downloads_url']}/#{@platform.name}#{subpath}"
-
end
-
-
1
def subpath
-
@subpath ||= @path.gsub(/^#{@platform.path}/, '')
-
end
-
-
1
def self.find_by_platform(platform, path, term)
-
# Strip out the non-ascii character
-
term = (term || '').strip.gsub(/[\\\/]+/, '')
-
.gsub(/[^\w\-\+\.]/, '_')
-
-
path = sanitize_path(path)
-
results = Dir.glob(File.join(platform.path, path, "*#{term}*"))
-
if term
-
results = results.sort_by(&:length)
-
else
-
results = results.sort
-
end
-
results.map{ |p| PlatformContent.new(platform, p) }
-
end
-
-
1
def self.remove_file(platform, path)
-
path = File.join(platform.path, sanitize_path(path))
-
FileUtils.rm_f(path) if File.exist?(path)
-
end
-
-
1
def self.sanitize_path(path)
-
path.split(File::SEPARATOR).map(&:strip).select(&:present?)
-
.map{ |p|
-
# Strip out the non-ascii character
-
p.gsub(/[\\\/]+/, '')
-
.gsub(/^[\.]+/, '')
-
.gsub(/[^\w\-\+\.]/, '_')
-
}.join(File::SEPARATOR)
-
end
-
-
end
-
1
class Product < ActiveRecord::Base
-
1
include TimeLiving
-
1
include Autostart
-
1
include EventLoggable
-
-
1
belongs_to :platform
-
1
belongs_to :project
-
1
has_many :product_build_lists, dependent: :destroy
-
-
1
validates :name, presence: true,
-
uniqueness: { scope: :platform_id },
-
length: { maximum: 100 }
-
-
1
validates :project, presence: true
-
1
validates :main_script, :params, length: { maximum: 255 }
-
-
1
scope :recent, -> { order(:name) }
-
-
1
attr_readonly :platform_id
-
-
1
def full_clone(attrs = {})
-
dup.tap do |c|
-
attrs.each {|k,v| c.send("#{k}=", v)}
-
c.time_living = c.time_living.to_i / 60 # see: TimeLiving#convert_time_living
-
c.platform_id = nil
-
c.product_build_lists = []
-
c.updated_at = nil; c.created_at = nil
-
end
-
end
-
-
1
class << self
-
1
Autostart::HUMAN_AUTOSTART_STATUSES.each do |autostart_status, human_autostart_status|
-
3
define_method "autostart_iso_builds_#{human_autostart_status}" do
-
autostart_iso_builds autostart_status
-
end
-
end
-
end
-
-
1
def self.autostart_iso_builds(autostart_status)
-
Product.where(autostart_status: autostart_status).each do |product|
-
pbl = product.product_build_lists.new
-
[:params, :main_script, :project, :project_version].each do |k|
-
pbl.send "#{k}=", product.send(k)
-
end
-
owner = product.platform.owner
-
pbl.user = owner.is_a?(User) ? owner : owner.owner
-
pbl.autostarted = true
-
pbl.base_url = "http://#{product.platform.default_host}"
-
pbl.time_living = product.time_living / 60
-
pbl.save
-
end
-
end
-
-
end
-
1
class ProductBuildList < ActiveRecord::Base
-
1
include CommitAndVersion
-
1
include TimeLiving
-
1
include FileStoreClean
-
1
include UrlHelper
-
1
include EventLoggable
-
1
include ProductBuildLists::Statusable
-
1
include ProductBuildLists::AbfWorkerable
-
-
1
LIVE_TIME = 2.week # for autostart
-
1
MAX_LIVE_TIME = 3.month # for manual start;
-
-
1
belongs_to :product
-
1
belongs_to :project
-
1
belongs_to :arch
-
1
belongs_to :user
-
-
# see: Issue #6
-
1
before_validation -> { self.arch_id = Arch.find_by(name: 'x86_64').id }, on: :create
-
# field "not_delete" can be changed only if build has been completed
-
1
before_validation -> { self.not_delete = false unless build_completed?; true }
-
-
1
validates :product, :product_id,
-
:project, :project_id,
-
:main_script,
-
:arch, :arch_id,
-
presence: true
-
1
validates :main_script, :params, length: { maximum: 255 }
-
-
1
attr_accessor :base_url, :product_name
-
-
1
attr_readonly :product_id
-
1
serialize :results, Array
-
-
-
1
scope :default_order, -> { order(updated_at: :desc) }
-
1
scope :for_user, -> (user) { where(user_id: user.id) }
-
1
scope :scoped_to_product_name, -> (product_name) {
-
joins(:product).where('products.name LIKE ?', "%#{product_name}%") if product_name.present?
-
}
-
1
scope :recent, -> { order(updated_at: :desc) }
-
1
scope :outdated, -> {
-
where(not_delete: false).
-
where("(#{table_name}.created_at < ? AND #{table_name}.autostarted is TRUE) OR #{table_name}.created_at < ?",
-
Time.now - LIVE_TIME, Time.now - MAX_LIVE_TIME)
-
}
-
-
1
after_initialize :init_project, if: :new_record?
-
-
1
def event_log_message
-
{product: product.name}.inspect
-
end
-
-
1
protected
-
-
1
def init_project
-
self.project ||= product.try(:project)
-
end
-
-
end
-
1
class Project < ActiveRecord::Base
-
1
has_ancestry orphan_strategy: :adopt # we replace a 'path' method in the Git module
-
-
1
include Autostart
-
1
include Owner
-
1
include Git
-
1
include Wiki
-
1
include UrlHelper
-
1
include EventLoggable
-
1
include Project::DefaultBranch
-
1
include Project::Finders
-
-
1
VISIBILITIES = ['open', 'hidden']
-
1
MAX_OWN_PROJECTS = 32000
-
1
NAME_REGEXP = /[\w\-\+\.]+/
-
1
OWNER_AND_NAME_REGEXP = /#{User::NAME_REGEXP.source}\/#{NAME_REGEXP.source}/
-
1
self.per_page = 25
-
-
1
belongs_to :owner, polymorphic: true, counter_cache: :own_projects_count
-
1
belongs_to :maintainer, class_name: 'User', optional: true
-
-
1
belongs_to :alias_from, class_name: 'Project', optional: true
-
1
has_many :aliases, class_name: 'Project', foreign_key: 'alias_from_id'
-
-
1
has_many :issues, dependent: :destroy
-
1
has_many :pull_requests, dependent: :destroy, foreign_key: 'to_project_id'
-
1
has_many :labels, dependent: :destroy
-
-
1
has_many :project_imports, dependent: :destroy
-
1
has_many :project_to_repositories, dependent: :destroy
-
1
has_many :repositories, through: :project_to_repositories
-
1
has_many :project_tags, dependent: :destroy
-
1
has_many :project_statistics, dependent: :destroy
-
-
1
has_many :build_lists, dependent: :destroy
-
1
has_many :hooks, dependent: :destroy
-
-
1
has_many :relations, as: :target, dependent: :destroy
-
1
has_many :collaborators, through: :relations, source: :actor, source_type: 'User'
-
1
has_many :groups, through: :relations, source: :actor, source_type: 'Group'
-
-
1
has_many :packages, class_name: 'BuildList::Package', dependent: :destroy
-
1
has_and_belongs_to_many :advisories # should be without dependent: :destroy
-
-
1
validates :name, uniqueness: { scope: [:owner_id, :owner_type], case_sensitive: false },
-
presence: true,
-
format: { with: /\A#{NAME_REGEXP.source}\z/,
-
message: I18n.t("activerecord.errors.project.uname") },
-
length: { maximum: 100 }
-
1
validates :maintainer, presence: true, unless: :new_record?
-
1
validates :url, presence: true, format: { with: /\Ahttps?:\/\/[\S]+\z/ }, if: :mass_import
-
1
validates :add_to_repository_id, presence: true, if: :mass_import
-
1
validates :visibility, presence: true, inclusion: { in: VISIBILITIES }
-
4
validate { errors.add(:base, :can_have_less_or_equal, count: MAX_OWN_PROJECTS) if owner.projects.size >= MAX_OWN_PROJECTS }
-
# throws validation error message from ProjectToRepository model into Project model
-
1
validate do |project|
-
3
project.project_to_repositories.each do |p_to_r|
-
next if p_to_r.valid?
-
p_to_r.errors.map(&:full_message).each{ |msg| errors[:base] << msg }
-
end
-
3
errors.delete :project_to_repositories
-
end
-
-
1
attr_readonly :owner_id, :owner_type
-
-
1
before_validation :truncate_name, on: :create
-
4
before_save -> { self.owner_uname = owner.uname if owner_uname.blank? || owner_id_changed? || owner_type_changed? }
-
1
before_create :set_maintainer
-
1
after_save :attach_to_personal_repository
-
1
before_update -> { update_path_to_project(name_was) }, if: :name_changed?
-
-
1
attr_accessor :url, :srpms_list, :mass_import, :add_to_repository_id
-
-
1
def init_mass_import
-
Project.perform_later :low, :run_mass_import, url, srpms_list, visibility, owner, add_to_repository_id
-
end
-
-
1
def name_with_owner
-
30
"#{owner_uname || owner.uname}/#{name}"
-
end
-
-
1
def to_param
-
name_with_owner
-
end
-
-
1
def all_members(*includes)
-
members(includes) | (owner_type == 'User' ? [owner] : owner.members.includes(includes))
-
end
-
-
1
def members(*includes)
-
collaborators.includes(includes) | groups.map{ |g| g.members.includes(includes) }.flatten
-
end
-
-
1
def add_member(member, role = 'admin')
-
Relation.add_member(member, self, role)
-
end
-
-
1
def remove_member(member)
-
Relation.remove_member(member, self)
-
end
-
-
1
def platforms
-
@platforms ||= repositories.map(&:platform).uniq
-
end
-
-
1
def admins
-
admins = self.collaborators.where("relations.role = 'admin'")
-
grs = self.groups.where("relations.role = 'admin'")
-
if self.owner.is_a? Group
-
grs = grs.where("relations.actor_id != ?", self.owner.id)
-
admins = admins | owner.members.where("relations.role = 'admin'")
-
end
-
admins = admins | grs.map(&:members).flatten # member of the admin group is admin
-
end
-
-
1
def public?
-
1
visibility == 'open'
-
end
-
-
1
def owner?(user)
-
owner == user
-
end
-
-
1
def git_project_address auth_user
-
opts = default_url_options
-
opts.merge!({user: auth_user.authentication_token, password: ''}) unless self.public?
-
Rails.application.routes.url_helpers.project_url(self.name_with_owner, opts) + '.git'
-
#path #share by NFS
-
end
-
-
1
def build_for(mass_build, repository_id, arch = Arch.find_by(name: 'i586'), priority = 0, increase_rt = false)
-
build_for_platform = mass_build.build_for_platform
-
save_to_platform = mass_build.save_to_platform
-
user = mass_build.user
-
# Select main and project platform repository(contrib, non-free and etc)
-
# If main does not exist, will connect only project platform repository
-
# If project platform repository is main, only main will be connect
-
main_rep_id = build_for_platform.repositories.main.first.try(:id)
-
include_repos = ([main_rep_id] << (save_to_platform.main? ? repository_id : nil)).compact.uniq
-
-
project_version = project_version_for save_to_platform, build_for_platform
-
-
increase_release_tag(project_version, user, "MassBuild##{mass_build.id}: Increase release tag") if increase_rt
-
-
build_list = build_lists.build do |bl|
-
bl.save_to_platform = save_to_platform
-
bl.build_for_platform = build_for_platform
-
bl.update_type = 'newpackage'
-
bl.arch = arch
-
bl.project_version = project_version
-
bl.user = user
-
bl.auto_publish_status = mass_build.auto_publish_status
-
bl.auto_create_container = mass_build.auto_create_container
-
bl.include_repos = include_repos
-
bl.extra_repositories = mass_build.extra_repositories
-
bl.extra_build_lists = mass_build.extra_build_lists
-
bl.priority = priority
-
bl.mass_build_id = mass_build.id
-
bl.save_to_repository_id = repository_id
-
bl.include_testing_subrepository = mass_build.include_testing_subrepository?
-
bl.use_cached_chroot = mass_build.use_cached_chroot?
-
bl.use_extra_tests = mass_build.use_extra_tests?
-
bl.external_nodes = mass_build.external_nodes
-
end
-
build_list.save
-
end
-
-
1
def fork(new_owner, new_name: nil, is_alias: false)
-
new_name = new_name.presence || name
-
dup.tap do |c|
-
c.name = new_name
-
c.parent_id = id
-
c.alias_from_id = is_alias ? (alias_from_id || id) : nil
-
c.owner = new_owner
-
c.updated_at = nil; c.created_at = nil # :id = nil
-
# Hack to call protected method :)
-
c.send :set_maintainer
-
c.save
-
end
-
end
-
-
1
def get_project_tag_sha1(tag, format)
-
format_id = ProjectTag::FORMATS["#{tag_file_format(format)}"]
-
project_tag = project_tags.where(tag_name: tag.name, format_id: format_id).first
-
-
return project_tag.sha1 if project_tag && project_tag.commit_id == tag.commit.id && FileStoreService::File.new(sha1: project_tag.sha1).exist?
-
-
archive = archive_by_treeish_and_format tag.name, format
-
sha1 = FileStoreService::File.new(data: archive).save
-
return nil if sha1.blank?
-
-
if project_tag
-
project_tag.destroy_files_from_file_store(project_tag.sha1)
-
project_tag.update(sha1: sha1)
-
else
-
project_tags.create(
-
tag_name: tag.name,
-
format_id: format_id,
-
commit_id: tag.commit.id,
-
sha1: sha1
-
)
-
end
-
return sha1
-
end
-
-
1
def archive_by_treeish_and_format(treeish, format)
-
@archive ||= create_archive treeish, format
-
end
-
-
# Finds release tag and increase its:
-
# 'Release: %mkrel 4mdk' => 'Release: 5mdk'
-
# 'Release: 4' => 'Release: 5'
-
# Finds release macros and increase it:
-
# '%define release %mkrel 4mdk' => '%define release 5mdk'
-
# '%define release 4' => '%define release 5'
-
1
def self.replace_release_tag(content)
-
-
build_new_release = Proc.new do |release, combine_release|
-
if combine_release.present?
-
r = combine_release.split('.').last.to_i
-
release << combine_release.gsub(/.[\d]+$/, '') << ".#{r + 1}"
-
else
-
release = release.to_i + 1
-
end
-
release
-
end
-
-
content.gsub(/^Release:(\s+)(%mkrel\s+)?(\d+)([.\d]+)?(mdk)?$/) do |line|
-
tab, mkrel, mdk = $1, $2, $5
-
"Release:#{tab}#{build_new_release.call($3, $4)}#{mdk}"
-
end.gsub(/^%define\s+release:?(\s+)(%mkrel\s+)?(\d+)([.\d]+)?(mdk)?$/) do |line|
-
tab, mkrel, mdk = $1, $2, $5
-
"%define release#{tab}#{build_new_release.call($3, $4)}#{mdk}"
-
end
-
end
-
-
1
class << self
-
1
Autostart::HUMAN_AUTOSTART_STATUSES.each do |autostart_status, human_autostart_status|
-
3
define_method "autostart_build_lists_#{human_autostart_status}" do
-
autostart_build_lists autostart_status
-
end
-
end
-
end
-
-
1
def self.autostart_build_lists(autostart_status)
-
Project.where(autostart_status: autostart_status).find_each do |p|
-
p.project_to_repositories.autostart_enabled.includes(repository: :platform).each do |p_to_r|
-
repository = p_to_r.repository
-
user = User.find(p_to_r.user_id)
-
if repository.platform.personal?
-
platforms = Platform.availables_main_platforms(user)
-
else
-
platforms = [repository.platform]
-
end
-
platforms.each do |platform|
-
platform.platform_arch_settings.by_default.pluck(:arch_id).each do |arch_id|
-
build_list = p.build_lists.build do |bl|
-
bl.save_to_platform = repository.platform
-
bl.build_for_platform = platform
-
bl.update_type = BuildList::UPDATE_TYPE_NEWPACKAGE
-
bl.arch_id = arch_id
-
bl.project_version = p.project_version_for(repository.platform, platform)
-
bl.user = user
-
bl.auto_publish_status = p_to_r.auto_publish? ? BuildList::AUTO_PUBLISH_STATUS_DEFAULT : BuildList::AUTO_PUBLISH_STATUS_NONE
-
bl.save_to_repository = repository
-
bl.include_repos = [platform.repositories.main.first.try(:id)].compact
-
if repository.platform.personal?
-
bl.extra_repositories = [repository.id]
-
else
-
bl.include_repos |= [repository.id]
-
end
-
end
-
build_list.save
-
end
-
end
-
end
-
end
-
end
-
-
1
def increase_release_tag(project_version, user, message)
-
blob, raw = find_blob_and_raw_of_spec_file(project_version)
-
return unless blob
-
-
content = self.class.replace_release_tag raw.content
-
return if content == raw.content
-
-
update_file(blob.name, content.gsub("\r", ''),
-
message: message,
-
actor: user,
-
head: project_version
-
)
-
end
-
-
1
protected
-
-
1
def create_archive(treeish, format)
-
file_name = "#{name}-#{treeish}"
-
fullname = "#{file_name}.#{tag_file_format(format)}"
-
file = Tempfile.new fullname, File.join(Rails.root, 'tmp')
-
system("cd #{path}; git archive --format=#{format == 'zip' ? 'zip' : 'tar'} --prefix=#{file_name}/ #{treeish} #{format == 'zip' ? '' : ' | gzip -9'} > #{file.path}")
-
file.close
-
{
-
path: file.path,
-
fullname: fullname
-
}
-
end
-
-
1
def tag_file_format(format)
-
format == 'zip' ? 'zip' : 'tar.gz'
-
end
-
-
1
def truncate_name
-
3
self.name = name.strip if name
-
end
-
-
1
def attach_to_personal_repository
-
3
owner_repos = self.owner.personal_platform.repositories
-
3
if is_package
-
3
repositories << self.owner.personal_repository unless repositories.exists?(id: owner_repos.pluck(:id))
-
else
-
repositories.delete owner_repos
-
end
-
end
-
-
1
def set_maintainer
-
3
if maintainer_id.blank?
-
3
self.maintainer_id = (owner_type == 'User') ? self.owner_id : self.owner.owner_id
-
end
-
end
-
-
1
def update_path_to_project(old_name)
-
new_name, new_path = name, path
-
self.name = old_name
-
old_path = path
-
self.name = new_name
-
FileUtils.mv old_path, new_path, force: true if Dir.exists?(old_path)
-
-
pull_requests_old_path = File.join(APP_CONFIG['git_path'], 'pull_requests', owner.uname, old_name)
-
if Dir.exists?(pull_requests_old_path)
-
FileUtils.mv pull_requests_old_path,
-
File.join(APP_CONFIG['git_path'], 'pull_requests', owner.uname, new_name),
-
force: true
-
end
-
-
PullRequest.where(from_project_id: id).update_all(from_project_name: new_name)
-
-
PullRequest.where(from_project_id: id).each{ |p| p.update_relations(old_name) }
-
pull_requests.where('from_project_id != to_project_id').each(&:update_relations)
-
end
-
1
later :update_path_to_project, queue: :middle
-
-
end
-
1
class ProjectImport < ActiveRecord::Base
-
1
belongs_to :project
-
1
belongs_to :platform
-
-
1
validates :name, uniqueness: { scope: :platform_id, case_sensitive: false }
-
1
validates :name, :platform, :version, presence: true
-
-
1
scope :by_name, ->(name) { where("#{table_name}.name ILIKE ?", name) }
-
-
1
after_initialize ->(r) { r.file_mtime ||= Time.current - 10.years } # default
-
end
-
1
class ProjectStatistic < ActiveRecord::Base
-
-
1
belongs_to :arch
-
1
belongs_to :project
-
-
1
validates :arch, :project, :average_build_time, :build_count, presence: true
-
1
validates :project_id, uniqueness: { scope: :arch_id }
-
end
-
1
class ProjectTag < ActiveRecord::Base
-
1
include FileStoreClean
-
-
1
FORMATS = {
-
'zip' => 0,
-
'tar.gz' => 1
-
}
-
-
1
belongs_to :project
-
-
1
validates :project, :commit_id, :sha1, :tag_name, :format_id, presence: true
-
1
validates :project_id, uniqueness: { scope: [:tag_name, :format_id] }
-
-
1
def sha1_of_file_store_files
-
[sha1]
-
end
-
end
-
1
class ProjectToRepository < ActiveRecord::Base
-
1
AUTOSTART_OPTIONS = %w(auto_publish user_id enabled)
-
-
1
belongs_to :project
-
1
belongs_to :repository
-
-
1
delegate :path, to: :project
-
-
1
scope :autostart_enabled, -> { where("autostart_options -> 'enabled' = 'true'") }
-
-
1
after_destroy :destroy_project_from_repository, unless: -> { Thread.current[:skip] }
-
-
1
validate :one_project_in_platform_repositories, on: :create
-
-
1
AUTOSTART_OPTIONS.each do |field|
-
3
store_accessor :autostart_options, field
-
end
-
-
1
def enabled?
-
['true', true].include?(enabled)
-
end
-
-
1
def auto_publish?
-
['true', true].include?(auto_publish)
-
end
-
-
1
protected
-
-
1
def destroy_project_from_repository
-
DestroyProjectFromRepositoryJob.perform(project, repository)
-
end
-
-
1
def one_project_in_platform_repositories
-
6
if Project.joins(repositories: :platform).where('platforms.id = ?', repository.platform_id).by_name(project.name).exists?
-
errors.add(:base, I18n.t('activerecord.errors.project_to_repository.project'))
-
end
-
end
-
end
-
1
class PullRequest < ActiveRecord::Base
-
STATUSES = [
-
1
STATUS_OPEN = 'open',
-
STATUS_READY = 'ready',
-
STATUS_ALREADY = 'already',
-
STATUS_BLOCKED = 'blocked',
-
STATUS_MERGED = 'merged',
-
STATUS_CLOSED = 'closed'
-
]
-
-
1
belongs_to :issue,
-
autosave: true,
-
dependent: :destroy,
-
touch: true,
-
validate: true
-
-
1
belongs_to :to_project,
-
class_name: 'Project',
-
foreign_key: 'to_project_id'
-
-
1
belongs_to :from_project,
-
class_name: 'Project',
-
foreign_key: 'from_project_id'
-
-
1
delegate :user,
-
:user_id,
-
:title,
-
:body,
-
:serial_id,
-
:assignee,
-
:status,
-
:to_param,
-
:created_at,
-
:updated_at,
-
:comments,
-
:status=,
-
to: :issue, allow_nil: true
-
-
1
validates :from_project, presence: true, on: :create
-
1
validates :to_project, presence: true
-
-
1
validate :uniq_merge, if: ->(pull) { pull.to_project.present? }
-
1
validates_each :from_ref, :to_ref do |record, attr, value|
-
check_ref record, attr, value
-
end
-
-
1
before_create :clean_dir
-
1
before_create :set_add_data
-
1
after_destroy :clean_dir
-
-
1
accepts_nested_attributes_for :issue
-
-
1
scope :needed_checking, -> { includes(:issue).where(issues: { status: [STATUS_OPEN, STATUS_BLOCKED, STATUS_READY] }) }
-
1
scope :not_closed_or_merged, -> { needed_checking }
-
1
scope :closed_or_merged, -> { where(issues: { status: [STATUS_CLOSED, STATUS_MERGED] }) }
-
-
1
state_machine :status, initial: :open do
-
1
event :ready do
-
1
transition [:ready, :open, :blocked] => :ready
-
end
-
-
1
event :already do
-
1
transition [:ready, :open, :blocked] => :already
-
end
-
-
1
event :block do
-
1
transition [:ready, :open, :blocked] => :blocked
-
end
-
-
1
event :merging do
-
1
transition ready: :merged
-
end
-
-
1
event :close do
-
1
transition [:ready, :open, :blocked] => :closed
-
end
-
-
1
event :reopen do
-
1
transition closed: :open
-
end
-
end
-
-
1
def update_relations(old_from_project_name = nil)
-
FileUtils.mv path(old_from_project_name), path, force: true if old_from_project_name
-
return unless Dir.exists?(path)
-
system 'git', '-C', path, 'remote', 'set-url', 'origin', to_project.path
-
system 'git', '-C', path, 'remote', 'set-url', 'head', from_project.path if cross_pull?
-
end
-
1
later :update_relations, queue: :middle
-
-
1
def cross_pull?
-
from_project_id != to_project_id
-
end
-
-
1
def check(do_transaction = true)
-
if do_transaction && !valid?
-
issue.set_close nil
-
issue.save(validate: false) # FIXME remove this hack
-
return false
-
end
-
res = merge
-
new_status = case res
-
when /Already up-to-date/, /Already up to date/
-
'already'
-
when /Merge made by/
-
system("cd #{path} && git reset --hard HEAD^") # remove merge commit
-
'ready'
-
when /Automatic merge failed/
-
system("cd #{path} && git reset --hard HEAD") # clean git index
-
'block'
-
else
-
raise res
-
end
-
-
if do_transaction
-
new_status == 'already' ? (ready; merging) : send(new_status)
-
self.update_inline_comments
-
else
-
self.status = new_status == 'block' ? STATUS_BLOCKED : new_status
-
end
-
end
-
-
1
def merge!(who)
-
return false unless can_merging?
-
old_commit = to_project.repo.commits(to_ref).first
-
commit = repo.commits(to_ref).first
-
system "git -C #{path} config user.name \"#{who.uname}\" && git -C #{path} config user.email \"#{who.email}\""
-
res = merge
-
if commit.id != repo.commits(to_ref).first.id
-
res2 = %x(export GL_ID=user-#{who.id} GL_REPO_NAME=#{to_project.path} && git -C #{path} push origin HEAD)
-
system("git -C #{path} reset --hard HEAD^") # for diff maybe FIXME
-
-
if old_commit.id == to_project.repo.commits(to_ref).first.id
-
raise "merge result pull_request #{id}: #{$?.exitstatus}; #{res2}; #{res}"
-
end
-
set_user_and_time who
-
merging
-
else # Try to catch no merge errors
-
raise "merge result pull_request #{id}: #{res}"
-
end
-
end
-
-
1
def path(suffix = from_project_name)
-
last_part = [id, from_project_owner_uname, suffix].compact.join('-')
-
File.join(APP_CONFIG['git_path'], "#{new_record? ? 'temp_' : ''}pull_requests", to_project.owner.uname, to_project.name, last_part)
-
end
-
-
1
def from_branch
-
cross_pull? ? "head_#{from_ref}" : from_ref
-
end
-
-
1
def common_ancestor
-
return @common_ancestor if @common_ancestor
-
base_commit = repo.commits(to_ref).first
-
@common_ancestor = repo.commit(repo.git.merge_base({}, base_commit, from_commit)) || base_commit
-
end
-
1
alias_method :to_commit, :common_ancestor
-
-
1
def diff_stats
-
@diff_stats ||= repo.diff_stats(to_commit.id, from_commit.id)
-
end
-
-
1
def diff
-
@diff ||= repo.diff(to_commit.id, from_commit.id)
-
end
-
-
1
def set_user_and_time user
-
issue.closed_at = Time.now.utc
-
issue.closer = user
-
end
-
-
1
def self.check_ref(record, attr, value)
-
project = attr == :from_ref ? record.from_project : record.to_project
-
return if project.blank?
-
if record.to_project.repo.branches.count > 0
-
record.errors.add attr, I18n.t('projects.pull_requests.wrong_ref') unless project.repo.branches_and_tags.map(&:name).include?(value)
-
else
-
record.errors.add attr, I18n.t('projects.pull_requests.empty_repo')
-
end
-
end
-
-
1
def uniq_merge
-
if to_project && to_project.pull_requests.needed_checking
-
.where(from_project_id: from_project_id,
-
to_ref: to_ref, from_ref: from_ref)
-
.where('pull_requests.id <> :id or :id is null', id: id).count > 0
-
errors.add(:base_branch, I18n.t('projects.pull_requests.duplicate', from_ref: from_ref))
-
end
-
end
-
-
1
def repo
-
@repo ||= Grit::Repo.new(path)
-
end
-
-
1
def from_commit
-
repo.commits(from_branch).first
-
end
-
-
1
protected
-
-
1
def system(*args)
-
Kernel.system(*args)
-
end
-
-
1
def merge
-
clone
-
message = "Merge pull request ##{serial_id} from #{from_project_owner_uname}/#{from_project_name}:#{from_ref}\r\n #{title}"
-
%x(cd #{path} && git checkout #{to_ref.shellescape} && git merge --no-ff #{from_branch.shellescape} -m #{message.shellescape})
-
end
-
-
1
def clone
-
return if from_project.nil?
-
git = Grit::Git.new(path)
-
if new_record? || !git.exist?
-
#~ FileUtils.mkdir_p(path)
-
#~ system("git clone --local --no-hardlinks #{to_project.path} #{path}")
-
options = {bare: false, shared: false, branch: to_ref} # shared?
-
`rm -rf #{path}`
-
git.fs_mkdir('..')
-
git.clone(options, to_project.path, path)
-
if cross_pull?
-
system 'git', '-C', path, 'remote', 'add', 'head', from_project.path
-
end
-
#clean # Need testing
-
end
-
-
system 'git', '-C', path, 'tag', '-d', from_ref, to_ref
-
system "git -C #{path} fetch --tags && git -C #{path} fetch --all"
-
-
tags, head = repo.tags.map(&:name), to_project == from_project ? 'origin' : 'head'
-
system 'git', '-C', path, 'checkout', to_ref
-
unless tags.include? to_ref
-
system 'git', '-C', path, 'reset', '--hard', "origin/#{to_ref}"
-
end
-
unless tags.include? from_ref
-
system 'git', '-C', path, 'branch', '-D', from_branch
-
system 'git', '-C', path, 'fetch', head, "+#{from_ref}:#{from_branch}"
-
system 'git', '-C', path, 'checkout', to_ref
-
end
-
end
-
-
1
def clean
-
to_project.repo.branches.each {|branch| system 'git', 'checkout', branch.name}
-
system 'git', '-C', path, 'checkout', to_ref
-
-
to_project.repo.branches.each do |branch|
-
system 'git', '-C', path, 'branch', '-D', branch.name unless [to_ref, from_branch].include? branch.name
-
end
-
to_project.repo.tags.each do |tag|
-
system 'git', '-C', path, 'tag', '-d', tag.name unless [to_ref, from_branch].include? tag.name
-
end
-
end
-
-
1
def clean_dir
-
FileUtils.rm_rf path
-
end
-
-
1
def update_inline_comments
-
self.comments.each do |c|
-
if c.data.present? # maybe need add new column 'actual'?
-
c.actual_inline_comment? diff, true
-
c.save
-
end
-
end
-
end
-
-
1
def set_add_data
-
self.from_project_owner_uname = from_project.owner.uname
-
self.from_project_name = from_project.name
-
end
-
end
-
1
class Relation < ActiveRecord::Base
-
1
ROLES = %w[reader writer admin]
-
-
1
belongs_to :target, polymorphic: true
-
1
belongs_to :actor, polymorphic: true, touch: true
-
-
1
validates :role, inclusion: { in: ROLES }
-
-
1
validates :target,
-
presence: true
-
-
1
validates :actor,
-
presence: true
-
-
# validate { errors.add(:actor, :taken) if Relation.where(actor_type: self.actor_type, actor_id: self.actor_id).present? }
-
1
before_validation :add_default_role
-
-
1
scope :by_user_through_groups, ->(u) {
-
where("actor_type = 'User' AND actor_id = ? OR actor_type = 'Group' AND actor_id IN (?)", u.id, u.group_ids)
-
}
-
1
scope :by_actor, ->(obj) { where(actor_id: obj.id, actor_type: obj.class.to_s) }
-
1
scope :by_target, ->(tar) { where(target_id: tar.id, target_type: tar.class.to_s) }
-
1
scope :by_role, ->(role) { where(role: role) }
-
-
1
def self.create_with_role(actor, target, role)
-
r = self.new
-
r.actor = actor
-
r.target = target
-
r.role = role
-
r.save
-
end
-
-
1
def self.add_member(member, target, role, relation = :relations)
-
if target.send(relation).exists?(actor_id: member.id, actor_type: member.class.to_s) || (target.respond_to?(:owner) && target.owner == member)
-
true
-
else
-
rel = target.send(relation).build(role: role)
-
rel.actor = member
-
rel.save
-
end
-
end
-
-
1
def self.remove_member(member, target)
-
return false if target.respond_to?(:owner) && target.owner == member
-
res = Relation.by_actor(member).by_target(target).each{|r| r.destroy}
-
if member.is_a?(User) && ['Project', 'Group'].include?(target.class.name)
-
member.check_assigned_issues target
-
end
-
res
-
end
-
-
1
protected
-
-
1
def add_default_role
-
42
self.role = ROLES.first if role.nil? || role.empty?
-
end
-
end
-
1
class Repository < ActiveRecord::Base
-
1
extend FriendlyId
-
1
friendly_id :name, use: [:finders]
-
-
1
include EventLoggable
-
1
include EmptyMetadata
-
-
1
LOCK_FILE_NAMES = { sync: '.sync.lock', repo: '.repo.lock' }
-
1
SORT = { 'base' => 1, 'main' => 2, 'contrib' => 3, 'non-free' => 4, 'restricted' => 5 }
-
-
1
belongs_to :platform
-
-
1
has_many :relations, as: :target, dependent: :destroy
-
1
has_many :actors, as: :target, class_name: 'Relation', dependent: :destroy
-
1
has_many :members, through: :actors, source: :actor, source_type: 'User'
-
-
1
has_many :project_to_repositories, dependent: :destroy, validate: true
-
1
has_many :projects, through: :project_to_repositories
-
1
has_many :repository_statuses, dependent: :destroy
-
1
has_one :key_pair, dependent: :destroy
-
-
1
has_many :build_lists, foreign_key: :save_to_repository_id, dependent: :destroy
-
-
1
validates :description, presence: true,
-
length: { maximum: 100 }
-
-
1
validates :name, uniqueness: { scope: :platform_id, case_sensitive: false },
-
presence: true,
-
format: { with: /\A[a-z0-9_\-]+\z/ },
-
length: { maximum: 100 }
-
-
1
validates :publish_builds_only_from_branch, length: { maximum: 255 }
-
-
1
scope :recent, -> { order(:name) }
-
1
scope :main, -> { where(name: %w(main base)) }
-
-
1
before_destroy :detele_directory
-
-
1
attr_readonly :name, :platform_id
-
1
attr_accessor :projects_list, :build_for_platform_id, :resign_rpms
-
-
1
def regenerate(build_for_platform_id = nil, resign_rpms = false)
-
build_for_platform = Platform.main.find build_for_platform_id if platform.personal?
-
status = repository_statuses.find_or_create_by(platform_id: build_for_platform.try(:id) || platform_id)
-
status.resign_rpms = resign_rpms
-
status.save
-
status.regenerate
-
end
-
-
1
def resign
-
if platform.main?
-
status = repository_statuses.find_or_create_by(platform_id: platform_id)
-
status.resign
-
end
-
end
-
-
1
def base_clone(attrs = {})
-
dup.tap do |c|
-
c.platform_id = nil
-
attrs.each {|k,v| c.send("#{k}=", v)}
-
c.updated_at = nil; c.created_at = nil
-
end
-
end
-
-
1
def clone_relations(from)
-
with_skip do
-
from.projects.find_each {|p| self.projects << p if self.projects.exclude?(p)}
-
end
-
end
-
1
later :clone_relations, loner: true, queue: :low
-
-
1
def add_projects(list, user)
-
list.lines.each do |line|
-
begin
-
line.chomp!; line.strip!
-
owner, name = line.split('/')
-
next if owner.blank? || name.blank?
-
-
project = ProjectPolicy::Scope.new(user, Project).read.where(owner_uname: owner, name: name).first
-
projects << project if project
-
rescue RuntimeError, Exception
-
end
-
end
-
end
-
1
later :add_projects, queue: :middle
-
-
1
def remove_projects(list)
-
list.lines.each do |name|
-
begin
-
name.chomp!; name.strip!
-
next if name.blank?
-
project_to_repositories.where(projects: { name: name }).joins(:project).readonly(false).destroy_all
-
rescue RuntimeError, Exception
-
end
-
end
-
end
-
1
later :remove_projects, queue: :middle
-
-
1
def full_clone(attrs = {})
-
base_clone(attrs).tap do |c|
-
with_skip {c.save} and c.clone_relations(self) # later with resque
-
end
-
end
-
-
# Checks locking of sync
-
1
def sync_lock_file_exists?
-
lock_file_actions :check, :sync
-
end
-
-
# Uses for locking sync
-
# Calls from UI
-
1
def add_sync_lock_file
-
lock_file_actions :add, :sync
-
end
-
-
# Uses for unlocking sync
-
# Calls from UI
-
1
def remove_sync_lock_file
-
lock_file_actions :remove, :sync
-
end
-
-
# Uses for locking publishing
-
# Calls from API
-
1
def add_repo_lock_file
-
lock_file_actions :add, :repo
-
end
-
-
# Uses for unlocking publishing
-
# Calls from API
-
1
def remove_repo_lock_file
-
lock_file_actions :remove, :repo
-
end
-
-
# Presence of `.repo.lock` file means that mirror is currently synchronising the repository state.
-
1
def repo_lock_file_exists?
-
lock_file_actions :check, :repo
-
end
-
-
1
def add_member(member, role = 'admin')
-
Relation.add_member(member, self, role)
-
end
-
-
1
def remove_member(member)
-
Relation.remove_member(member, self)
-
end
-
-
1
class << self
-
1
def build_stub(platform)
-
rep = Repository.new
-
rep.platform = platform
-
rep
-
end
-
end
-
-
1
def destroy
-
with_skip {super} # avoid cascade XML RPC requests
-
end
-
1
later :destroy, queue: :low
-
-
1
def self.custom_sort(repos)
-
repos.select{ |r| SORT.keys.include?(r.name) }.sort{ |a,b| SORT[a.name] <=> SORT[b.name] } | repos.sort_by(&:name)
-
end
-
-
1
protected
-
-
1
def lock_file_actions(action, lock_file)
-
result = false
-
(['SRPMS'] << Arch.pluck(:name)).each do |arch|
-
path = "#{platform.path}/repository/#{arch}/#{name}/#{LOCK_FILE_NAMES[lock_file]}"
-
case action
-
when :add
-
result ||= FileUtils.touch(path) rescue nil
-
when :remove
-
result ||= FileUtils.rm_f(path)
-
when :check
-
return true if File.exist?(path)
-
end
-
end
-
return result
-
end
-
-
1
def detele_directory
-
return unless platform
-
repository_path = platform.path << '/repository'
-
if platform.personal?
-
Platform.main.pluck(:name).each do |main_platform_name|
-
detele_repositories_directory "#{repository_path}/#{main_platform_name}"
-
end
-
else
-
detele_repositories_directory repository_path
-
end
-
end
-
-
1
def detele_repositories_directory(repository_path)
-
srpm_and_arches = (['SRPM'] << Arch.pluck(:name)).join(',')
-
`sh -c 'rm -rf #{repository_path}/{#{srpm_and_arches}}/#{name}'`
-
end
-
-
end
-
1
class RepositoryStatus < ActiveRecord::Base
-
1
include FileStoreClean
-
1
include RegenerationStatus
-
-
1
WAITING_FOR_RESIGN = 300
-
1
PUBLISH = 400
-
1
RESIGN = 500
-
1
WAITING_FOR_RESIGN_AFTER_PUBLISH = 600
-
1
WAITING_FOR_RESIGN_AFTER_REGENERATION = 700
-
1
WAITING_FOR_REGENERATION_AFTER_PUBLISH = 800
-
1
WAITING_FOR_REGENERATION_AFTER_RESIGN = 900
-
1
WAITING_FOR_RESIGN_AND_REGENERATION_AFTER_PUBLISH = 1000
-
1
WAITING_FOR_RESIGN_AND_REGENERATION = 1100
-
-
-
1
HUMAN_STATUSES = HUMAN_STATUSES.clone.merge({
-
WAITING_FOR_RESIGN => :waiting_for_resign,
-
PUBLISH => :publish,
-
RESIGN => :resign,
-
WAITING_FOR_RESIGN_AFTER_PUBLISH => :waiting_for_resign_after_publish,
-
WAITING_FOR_RESIGN_AFTER_REGENERATION => :waiting_for_resign_after_regeneration,
-
WAITING_FOR_REGENERATION_AFTER_PUBLISH => :waiting_for_regeneration_after_publish,
-
WAITING_FOR_REGENERATION_AFTER_RESIGN => :waiting_for_regeneration_after_resign,
-
WAITING_FOR_RESIGN_AND_REGENERATION_AFTER_PUBLISH => :waiting_for_resign_and_regeneration_after_publish,
-
WAITING_FOR_RESIGN_AND_REGENERATION => :waiting_for_resign_and_regeneration
-
}).freeze
-
-
1
belongs_to :platform
-
1
belongs_to :repository
-
-
1
validates :repository, :platform, presence: true
-
1
validates :repository_id, uniqueness: { scope: :platform_id }
-
-
1
scope :platform_ready, -> { where(platforms: {status: READY}).joins(:platform) }
-
1
scope :for_regeneration, -> { where(status: WAITING_FOR_REGENERATION) }
-
1
scope :for_resign, -> { where(status: [WAITING_FOR_RESIGN, WAITING_FOR_RESIGN_AND_REGENERATION]) }
-
1
scope :not_ready, -> { where('repository_statuses.status != ?', READY) }
-
-
1
state_machine :status, initial: :ready do
-
1
event :ready do
-
1
transition [:regenerating, :publish, :resign] => :ready
-
1
transition [:waiting_for_resign_after_publish, :waiting_for_resign_after_regeneration] => :waiting_for_resign
-
1
transition [:waiting_for_regeneration_after_publish, :waiting_for_regeneration_after_resign] => :waiting_for_regeneration
-
1
transition waiting_for_resign_and_regeneration_after_publish: :waiting_for_resign_and_regeneration
-
end
-
-
1
event :regenerate do
-
1
transition ready: :waiting_for_regeneration
-
1
transition publish: :waiting_for_regeneration_after_publish
-
1
transition resign: :waiting_for_regeneration_after_resign
-
1
transition waiting_for_resign_after_publish: :waiting_for_resign_and_regeneration_after_publish
-
1
transition waiting_for_resign: :waiting_for_resign_and_regeneration
-
end
-
-
1
event :start_regeneration do
-
1
transition waiting_for_regeneration: :regenerating
-
1
transition waiting_for_resign_and_regeneration: :waiting_for_resign_after_regeneration
-
end
-
-
1
event :resign do
-
1
transition ready: :waiting_for_resign
-
1
transition publish: :waiting_for_resign_after_publish
-
1
transition waiting_for_regeneration: :waiting_for_resign_and_regeneration
-
1
transition waiting_for_regeneration_after_publish: :waiting_for_resign_and_regeneration_after_publish
-
1
transition regenerating: :waiting_for_resign_after_regeneration
-
end
-
-
1
event :start_resign do
-
1
transition waiting_for_resign: :resign
-
1
transition waiting_for_resign_and_regeneration: :waiting_for_regeneration_after_resign
-
end
-
-
1
event :publish do
-
1
transition ready: :publish
-
end
-
-
1
HUMAN_STATUSES.each do |code,name|
-
12
state name, value: code
-
end
-
end
-
end
-
1
require 'ohm'
-
1
require 'ohm/expire'
-
-
1
class RpmBuildNode < Ohm::Model
-
1
include Ohm::Expire
-
-
1
TTL = 120
-
-
1
expire TTL
-
-
1
attribute :user_id
-
1
attribute :worker_count
-
1
attribute :busy_workers
-
1
attribute :system
-
1
attribute :host
-
1
attribute :query_string
-
1
attribute :last_build_id
-
-
1
def user
-
User.where(id: user_id).first
-
end
-
-
1
def self.total_statistics
-
systems, others, busy = 0, 0, 0
-
RpmBuildNode.all.select{ |n| n.user_id }.each do |n|
-
if n.system == 'true'
-
systems += n.worker_count.to_i
-
else
-
others += n.worker_count.to_i
-
end
-
busy += n.busy_workers.to_i
-
end
-
{ systems: systems, others: others, busy: busy }
-
end
-
end
-
1
class Search < Struct.new(:query, :user, :paginate_params)
-
1
include ActiveModel::Conversion
-
1
extend ActiveModel::Naming
-
-
1
TYPES = %w(projects users groups platforms)
-
-
-
1
TYPES.each do |type|
-
4
define_method type do
-
find_collection(type)
-
end
-
end
-
-
1
private
-
-
1
def find_collection(type)
-
scope =
-
if type == 'users'
-
User.opened
-
else
-
klass = type.classify.constantize
-
"#{klass}Policy::Scope".constantize.new(user, klass).show
-
end
-
scope.search_like(query).
-
search_order.
-
paginate(paginate_params)
-
end
-
-
end
-
1
class SettingsNotifier < ActiveRecord::Base
-
1
belongs_to :user
-
-
1
validates :user, presence: true
-
-
end
-
# This class is based on
-
# https://github.com/gitlabhq/gitlabhq/blob/15c0e58a49d623a0f8747e1d7e74364324eeb79f/app/models/key.rb
-
-
1
class SshKey < ActiveRecord::Base
-
1
SHELL_KEY_COMMAND = "/home/#{APP_CONFIG['shell_user']}/gitlab-shell/bin/gitlab-keys"
-
-
1
belongs_to :user
-
-
1
before_validation -> { self.key = key.strip if key.present? }
-
1
before_validation :set_fingerprint
-
-
1
validates :name, length: { maximum: 255 }
-
1
validates :key, length: { maximum: 5000 }, format: { with: /ssh-.{3} / } # Public key?
-
1
validates :fingerprint, uniqueness: true, presence: { message: I18n.t('activerecord.errors.ssh_key.wrong_key') }
-
-
1
after_create :add_key
-
1
before_destroy :remove_key
-
-
1
protected
-
-
1
def set_fingerprint
-
return false unless key
-
-
file = Tempfile.new('key_file', '/tmp')
-
filename = file.path
-
begin
-
file.puts key
-
file.rewind
-
fingerprint_output = `ssh-keygen -lf #{file.path} 2>&1` # Catch stderr.
-
exitstatus = $?.exitstatus
-
ensure
-
file.close
-
file.unlink # deletes the temp file
-
end
-
if exitstatus != 0
-
self.fingerprint = nil
-
else
-
self.fingerprint = fingerprint_output.split.try :[], 1
-
if name.blank?
-
s = fingerprint_output.split.try :[], 2
-
if filename == s # no identificator
-
start = key =~ /ssh-.{3} /
-
self.name = key[start..start+26] # taken first 26 characters
-
else
-
self.name = s
-
end
-
end
-
end
-
end
-
-
1
def key_id
-
"key-#{id}"
-
end
-
-
1
def add_key
-
system "#{SHELL_KEY_COMMAND} add-key #{key_id} \"#{key}\"" # Safety?
-
end
-
-
1
def remove_key
-
system "#{SHELL_KEY_COMMAND} rm-key #{key_id}"# \"#{key}\""
-
end
-
-
end
-
1
class Statistic < ActiveRecord::Base
-
KEYS = [
-
1
KEY_COMMIT = 'commit',
-
KEY_BUILD_LIST = 'build_list',
-
KEY_BUILD_LIST_BUILD_STARTED = "#{KEY_BUILD_LIST}.#{BuildList::BUILD_STARTED}",
-
KEY_BUILD_LIST_SUCCESS = "#{KEY_BUILD_LIST}.#{BuildList::SUCCESS}",
-
KEY_BUILD_LIST_BUILD_ERROR = "#{KEY_BUILD_LIST}.#{BuildList::BUILD_ERROR}",
-
KEY_BUILD_LIST_BUILD_PUBLISHED = "#{KEY_BUILD_LIST}.#{BuildList::BUILD_PUBLISHED}",
-
KEY_ISSUE = 'issue',
-
KEY_ISSUES_OPEN = "#{KEY_ISSUE}.#{Issue::STATUS_OPEN}",
-
KEY_ISSUES_REOPEN = "#{KEY_ISSUE}.#{Issue::STATUS_REOPEN}",
-
KEY_ISSUES_CLOSED = "#{KEY_ISSUE}.#{Issue::STATUS_CLOSED}",
-
KEY_PULL_REQUEST = 'pull_request',
-
KEY_PULL_REQUESTS_OPEN = "#{KEY_PULL_REQUEST}.#{PullRequest::STATUS_OPEN}",
-
KEY_PULL_REQUESTS_MERGED = "#{KEY_PULL_REQUEST}.#{PullRequest::STATUS_MERGED}",
-
KEY_PULL_REQUESTS_CLOSED = "#{KEY_PULL_REQUEST}.#{PullRequest::STATUS_CLOSED}",
-
]
-
-
1
belongs_to :user
-
1
belongs_to :project
-
-
1
validates :user_id,
-
uniqueness: { scope: [:project_id, :key, :activity_at] },
-
presence: true
-
-
1
validates :email,
-
presence: true
-
-
1
validates :project_id,
-
presence: true
-
-
1
validates :project_name_with_owner,
-
presence: true
-
-
1
validates :key,
-
presence: true
-
-
1
validates :counter,
-
presence: true
-
-
1
validates :activity_at,
-
presence: true
-
-
1
scope :for_period, -> (start_date, end_date) {
-
where(activity_at: (start_date..end_date))
-
}
-
1
scope :for_users, -> (user_ids) {
-
where(user_id: user_ids) if user_ids.present?
-
}
-
1
scope :for_groups, -> (group_ids) {
-
where(["project_id = ANY (
-
ARRAY (
-
SELECT target_id
-
FROM relations
-
INNER JOIN projects ON projects.id = relations.target_id
-
WHERE relations.target_type = 'Project' AND
-
projects.owner_type = 'Group' AND
-
relations.actor_type = 'Group' AND
-
relations.actor_id IN (:groups)
-
)
-
)", { groups: group_ids }
-
]) if group_ids.present?
-
}
-
-
1
scope :build_lists_started, -> { where(key: KEY_BUILD_LIST_BUILD_STARTED) }
-
1
scope :build_lists_success, -> { where(key: KEY_BUILD_LIST_SUCCESS) }
-
1
scope :build_lists_error, -> { where(key: KEY_BUILD_LIST_BUILD_ERROR) }
-
1
scope :build_lists_published, -> { where(key: KEY_BUILD_LIST_BUILD_PUBLISHED) }
-
1
scope :commits, -> { where(key: KEY_COMMIT) }
-
1
scope :issues_open, -> { where(key: KEY_ISSUES_OPEN) }
-
1
scope :issues_reopen, -> { where(key: KEY_ISSUES_REOPEN) }
-
1
scope :issues_closed, -> { where(key: KEY_ISSUES_CLOSED) }
-
1
scope :pull_requests_open, -> { where(key: KEY_PULL_REQUESTS_OPEN) }
-
1
scope :pull_requests_merged, -> { where(key: KEY_PULL_REQUESTS_MERGED) }
-
1
scope :pull_requests_closed, -> { where(key: KEY_PULL_REQUESTS_CLOSED) }
-
-
-
1
def self.now_statsd_increment(activity_at: nil, user_id: nil, project_id: nil, key: nil, counter: 1)
-
# Truncates a DateTime to the minute
-
3
activity_at = activity_at.utc.change(min: 0)
-
3
user = User.find user_id
-
3
project = Project.find project_id
-
3
Statistic.create(
-
user_id: user_id,
-
email: user.email,
-
project_id: project_id,
-
project_name_with_owner: project.name_with_owner,
-
key: key,
-
activity_at: activity_at
-
)
-
rescue ActiveRecord::RecordNotUnique
-
# Do nothing, see: ensure
-
ensure
-
Statistic.where(
-
user_id: user_id,
-
project_id: project_id,
-
key: key,
-
activity_at: activity_at
-
3
).update_all(['counter = counter + ?', counter]) if user_id.present? && project_id.present?
-
end
-
-
1
def self.statsd_increment(options = {})
-
3
Statistic.perform_later(:middle, :now_statsd_increment, options)
-
end
-
-
end
-
1
class Subscribe < ActiveRecord::Base
-
1
belongs_to :user
-
1
belongs_to :project, optional: true
-
-
1
validates :user, presence: true
-
-
1
def subscribeable
-
if commit_subscribe?
-
project.repo.commit(Subscribe.hex_to_commit_hash commentable_id)
-
else
-
subscribeable_type.constantize.find_by_id(subscribeable_id)
-
end
-
end
-
-
1
def subscribeable=(c)
-
if self.class.commit_subscribe?(c.class)
-
self.subscribeable_id = c.id.hex
-
else
-
self.subscribeable_id = c.id
-
end
-
self.subscribeable_type = c.class.name
-
end
-
-
1
def self.commit_subscribe?(class_name)
-
class_name.to_s == 'Grit::Commit'
-
end
-
-
1
def commit_subscribe?
-
self.class.commit_subscribe?(subscribeable_type)
-
end
-
-
1
def subscribed?
-
status
-
end
-
-
1
def self.comment_subscribes(comment)
-
Subscribe.where(subscribeable_id: comment.commentable_id, subscribeable_type: comment.commentable.class.name, project_id: comment.project)
-
end
-
-
1
def self.subscribed_to_commit?(project, user, commit)
-
subscribe = user.subscribes.where(subscribeable_id: commit.id.hex, subscribeable_type: commit.class.name, project_id: project.id).first
-
return subscribe.subscribed? if subscribe # return status if already subscribe present
-
true
-
end
-
-
1
def self.subscribe_to_commit(options)
-
Subscribe.set_subscribe_to_commit(options, true)
-
end
-
-
1
def self.unsubscribe_from_commit(options)
-
Subscribe.set_subscribe_to_commit(options, false)
-
end
-
-
1
def self.hex_to_commit_hash hex
-
# '079d'.hex.to_s(16) => "79d"
-
t = hex.to_s(16)
-
'0'*(40-t.length) << t # commit hash has 40-character
-
end
-
-
1
private
-
-
1
def self.set_subscribe_to_commit(options, status)
-
if subscribe = Subscribe.where(options).first
-
subscribe.update(status: status)
-
else
-
Subscribe.create options.merge(status: status)
-
end
-
end
-
-
end
-
1
class Token < ActiveRecord::Base
-
1
belongs_to :subject, polymorphic: true, touch: true
-
1
belongs_to :creator, class_name: 'User'
-
1
belongs_to :updater, class_name: 'User', optional: true
-
-
1
validates :creator_id, :subject_id, :subject_type, presence: true
-
1
validates :authentication_token, presence: true, uniqueness: { case_sensitive: true }
-
1
validates :description, length: { maximum: 1000 }
-
-
1
default_scope { order(created_at: :desc) }
-
1
scope :by_active, -> { where(status: 'active') }
-
-
1
before_validation :generate_token, on: :create
-
-
1
state_machine :status, initial: :active do
-
1
event :block do
-
1
transition [:active, :blocked] => :blocked
-
end
-
end
-
-
1
protected
-
-
1
def generate_token
-
self.authentication_token = loop do
-
token = SecureRandom.urlsafe_base64(32)
-
break token unless Token.where(authentication_token: token).exists?
-
end
-
end
-
-
end
-
1
class User < Avatar
-
1
extend FriendlyId
-
1
friendly_id :uname, use: [:finders]
-
-
1
include PersonalRepository
-
1
include ActsLikeMember
-
1
include Feed::User
-
1
include EventLoggable
-
1
include TokenAuthenticatable
-
-
1
ROLES = ['', 'admin', 'banned', 'tester']
-
1
EXTENDED_ROLES = ROLES | ['system']
-
1
LANGUAGES_FOR_SELECT = [['Russian', 'ru'], ['English', 'en']]
-
1
LANGUAGES = LANGUAGES_FOR_SELECT.map(&:last)
-
1
NAME_REGEXP = /[a-z0-9_]+/
-
-
1
devise :database_authenticatable, :registerable, :recoverable,
-
:rememberable, :validatable, :lockable, :confirmable
-
-
1
has_one :notifier, class_name: 'SettingsNotifier', dependent: :destroy #:notifier
-
1
has_one :builds_setting, class_name: 'UserBuildsSetting', dependent: :destroy
-
-
1
has_many :activity_feeds, dependent: :destroy
-
-
1
has_many :build_lists, dependent: :destroy
-
1
has_many :subscribes, foreign_key: :user_id, dependent: :destroy
-
1
has_many :comments, dependent: :destroy
-
-
1
has_many :relations, as: :actor, dependent: :destroy
-
1
has_many :targets, as: :actor, class_name: 'Relation', dependent: :destroy
-
-
1
has_many :projects, through: :targets, source: :target, source_type: 'Project', autosave: true
-
1
has_many :groups, through: :targets, source: :target, source_type: 'Group', autosave: true
-
1
has_many :platforms, through: :targets, source: :target, source_type: 'Platform', autosave: true
-
1
has_many :repositories, through: :targets, source: :target, source_type: 'Repository'
-
-
1
has_many :own_projects, as: :owner, class_name: 'Project', dependent: :destroy
-
1
has_many :own_groups, foreign_key: :owner_id, class_name: 'Group', dependent: :destroy
-
1
has_many :own_platforms, as: :owner, class_name: 'Platform', dependent: :destroy
-
1
has_many :issues
-
1
has_many :assigned_issues, foreign_key: :assignee_id, class_name: 'Issue', dependent: :nullify
-
-
1
has_many :key_pairs
-
1
has_many :ssh_keys, dependent: :destroy
-
-
1
has_many :invites, dependent: :destroy
-
1
has_one :invitation, class_name: 'Invite', foreign_key: :invited_user_id, dependent: :destroy
-
-
1
validates :uname, presence: true,
-
uniqueness: { case_sensitive: false },
-
format: { with: /\A#{NAME_REGEXP.source}\z/ },
-
reserved_name: true,
-
length: { maximum: 30 }
-
1
validates :name, length: { maximum: 100 }
-
-
13
validate { errors.add(:uname, :taken) if Group.by_uname(uname).present? }
-
1
validates :role, inclusion: { in: EXTENDED_ROLES }, allow_blank: true
-
1
validates :language, inclusion: { in: LANGUAGES }, allow_blank: true
-
-
1
attr_readonly :uname
-
1
attr_accessor :login, :delete_avatar, :invite_key
-
-
1
scope :opened, -> { where('users.role != \'system\' OR users.role IS NULL') }
-
1
scope :real, -> { where(role: ['', nil]) }
-
6
EXTENDED_ROLES.select { |type| type.present?}.each do |type|
-
4
scope type.to_sym, -> { where(role: type) }
-
end
-
-
1
scope :member_of_project, ->(item) {
-
where 'users.id IN (?)', item.members.map(&:id).uniq
-
}
-
-
13
after_create -> { self.create_notifier unless self.system? }
-
1
before_create :ensure_authentication_token
-
-
1
def admin?
-
role == 'admin'
-
end
-
-
1
def user?
-
persisted?
-
end
-
-
1
def guest?
-
3
new_record?
-
end
-
-
1
def tester?
-
role == 'tester'
-
end
-
-
1
def system?
-
24
role == 'system'
-
end
-
-
1
def access_locked?
-
6
role == 'banned'
-
end
-
-
1
def fullname
-
return name.present? ? "#{uname} (#{name})" : uname
-
end
-
-
1
def user_appeal
-
24
name.presence || uname
-
end
-
-
1
class << self
-
1
def find_for_database_authentication(warden_conditions)
-
conditions = warden_conditions.dup
-
login = conditions.delete(:login)
-
where(conditions)
-
.where(["lower(uname) = :value OR lower(email) = :value OR authentication_token = :orig_value",
-
{ value: login.downcase, orig_value: login }]).first
-
end
-
-
1
def auth_by_token_or_login_pass(user, pass)
-
u = User.find_for_database_authentication(login: user)
-
u if u && !u.access_locked? && (u.authentication_token == user || u.valid_password?(pass))
-
end
-
end
-
-
# def update_with_password(params={})
-
# params.delete(:current_password)
-
# # self.update_without_password(params) # Don't allow password update
-
# if params[:password].blank?
-
# params.delete(:password)
-
# params.delete(:password_confirmation) if params[:password_confirmation].blank?
-
# end
-
# result = update(params)
-
# clean_up_passwords
-
# result
-
# end
-
-
1
def commentor?(commentable)
-
comments.exists?(commentable_type: commentable.class.name, commentable_id: commentable.id.hex)
-
end
-
-
1
def committer?(commit)
-
email.downcase == commit.committer.email.downcase
-
end
-
-
1
def owner_of? object
-
if object.respond_to? :owner
-
object.owner_id == self.id or self.group_ids.include? object.owner_id
-
else
-
false
-
end
-
end
-
-
1
def best_role target
-
return nil if target.nil?
-
roles = target_roles(target)
-
return nil if roles.count == 0
-
%w(admin writer reader).each {|role| return role if roles.include?(role)}
-
raise "unknown user #{self.uname} roles #{roles}"
-
end
-
-
1
def check_assigned_issues target
-
if target.is_a? Project
-
assigned_issues.where(project_id: target.id).update_all(assignee_id: nil)
-
else
-
project_ids = ProjectPolicy::Scope.new(self, Project).membered.distinct.pluck(:id)
-
-
issues = assigned_issues
-
issues = issues.where('project_id not in (?)', project_ids) if project_ids.present?
-
issues.update_all(assignee_id: nil)
-
end
-
end
-
-
1
protected
-
-
1
def target_roles target
-
rel, gr, roles = target.relations, self.groups, []
-
-
if target.owner.class == Group
-
owner_group = self.groups.where(id: target.owner.id).first
-
roles += owner_group.actors.where(actor_id: self) if owner_group# user group is owner
-
-
gr = gr.where('groups.id != ?', target.owner.id) # exclude target owner group from users group list
-
end
-
-
if target.class == Group
-
roles += target.actors.where(actor_id: self.id, actor_type: 'User') # user is member of a target group
-
else
-
roles += rel.where(actor_id: gr.pluck(Arel.sql('DISTINCT groups.id')), actor_type: 'Group') # user group is member
-
end
-
roles += rel.where(actor_id: self.id, actor_type: 'User') # user is member
-
roles.map(&:role).uniq
-
end
-
-
end
-
1
class UserBuildsSetting < ActiveRecord::Base
-
1
include ExternalNodable
-
-
1
belongs_to :user
-
-
1
validates :user, presence: true
-
-
end
-
1
class WikiPage < Struct.new(:page, :format, :content, :footer, :sidebar)
-
1
include ActiveModel::Conversion
-
1
extend ActiveModel::Naming
-
-
1
attr_accessor :message, :rename
-
-
1
def rename
-
@rename ||= page
-
end
-
-
end
-
1
class AdvisoryPolicy < ApplicationPolicy
-
-
1
def index?
-
true
-
end
-
1
alias_method :search?, :index?
-
1
alias_method :show?, :index?
-
-
1
def create?
-
!user.guest?
-
end
-
1
alias_method :update?, :create?
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(
-
description
-
references
-
)
-
end
-
-
end
-
1
class ApplicationPolicy
-
1
attr_reader :user, :record
-
-
1
def initialize(user, record)
-
# raise Pundit::NotAuthorizedError, 'must be logged in' unless user
-
9
@user = user || User.new
-
9
@record = record
-
end
-
-
1
BASIC_ACTIONS = %i(index? show? create? update? destroy? destroy_all?)
-
-
1
def index?
-
false
-
end
-
-
1
def show?
-
false
-
end
-
-
1
def new?
-
1
create?
-
end
-
-
1
def edit?
-
update?
-
end
-
-
1
def update?
-
false
-
end
-
-
1
def create?
-
false
-
end
-
-
1
def destroy?
-
false
-
end
-
-
1
def permitted_attributes
-
[]
-
end
-
-
1
class Scope
-
1
attr_reader :user, :scope
-
-
1
def initialize(user, scope)
-
@user = user
-
@scope = scope
-
end
-
-
1
def resolve
-
scope
-
end
-
end
-
-
# Public: Get user's group ids.
-
#
-
# Returns the Array of group ids.
-
1
def user_group_ids
-
Rails.cache.fetch(['ApplicationPolicy#user_group_ids', user]) do
-
user.group_ids
-
end
-
end
-
-
1
protected
-
-
# Public: Check if provided user is the current user.
-
#
-
# Returns true if it is, false otherwise.
-
1
def current_user?(u)
-
u == user
-
end
-
-
# Public: Check if provided user is guest.
-
#
-
# Returns true if he is, false otherwise.
-
1
def is_guest?
-
user.new_record?
-
end
-
-
# Public: Check if provided user is user.
-
#
-
# Returns true if he is, false otherwise.
-
1
def is_user?
-
user.persisted?
-
end
-
-
# Public: Check if provided user is tester.
-
#
-
# Returns true if he is, false otherwise.
-
1
def is_tester?
-
user.role == 'tester'
-
end
-
-
# Public: Check if provided user is system.
-
#
-
# Returns true if he is, false otherwise.
-
1
def is_system?
-
user.role == 'system'
-
end
-
-
# Public: Check if provided user is admin.
-
#
-
# Returns true if he is, false otherwise.
-
1
def is_admin?
-
6
user.role == 'admin'
-
end
-
-
# Public: Check if provided user is banned.
-
#
-
# Returns true if he is, false otherwise.
-
1
def is_banned?
-
user.role == 'banned'
-
end
-
-
# Private: Check if provided user is at least record admin.
-
#
-
# Returns true if he is, false otherwise.
-
1
def local_admin?(r = record)
-
owner?(r) || best_role(r) == 'admin'
-
end
-
-
# Private: Check if provided user is at least record reader.
-
#
-
# Returns true if he is, false otherwise.
-
1
def local_reader?(r = record)
-
owner?(r) || %w(reader writer admin).include?(best_role(r))
-
end
-
-
# Private: Check if provided user is at least record writer.
-
#
-
# Returns true if he is, false otherwise.
-
1
def local_writer?(r = record)
-
owner?(r) || %w(writer admin).include?(best_role(r))
-
end
-
-
# Private: Check if provided user is record owner.
-
#
-
# Returns true if he is, false otherwise.
-
1
def owner?(r = record)
-
(
-
3
!r.try(:owner_type) && r.owner_id == user.id
-
) || (
-
3
r.try(:owner_type) == 'User' && r.owner_id == user.id
-
) || (
-
r.try(:owner_type) == 'Group' && user_own_group_ids.include?(r.owner_id)
-
)
-
end
-
-
# Private: Get the best role of user for record.
-
#
-
# Returns the String role or nil.
-
1
def best_role(r = record)
-
Rails.cache.fetch(['ApplicationPolicy#best_role', r, user]) do
-
user.best_role(r)
-
end
-
end
-
-
# Public: Get own user's group ids.
-
#
-
# Returns the Array of own group ids.
-
1
def user_own_group_ids
-
Rails.cache.fetch(['ApplicationPolicy#user_own_group_ids', user]) do
-
user.own_group_ids
-
end
-
end
-
-
# Public: Get user's platform ids.
-
#
-
# Returns the Array of platform ids.
-
1
def user_platform_ids
-
Rails.cache.fetch(['ApplicationPolicy#user_platform_ids', user]) do
-
user.repositories.pluck(:platform_id)
-
end
-
end
-
-
end
-
1
class ArchPolicy < ApplicationPolicy
-
-
1
def index?
-
true
-
end
-
end
-
1
class BuildListPolicy < ApplicationPolicy
-
-
1
def index?
-
true
-
end
-
-
1
def show?
-
record.user_id == user.id || ProjectPolicy.new(user, record.project).show?
-
end
-
1
alias_method :read?, :show?
-
1
alias_method :log?, :show?
-
1
alias_method :everything?, :show?
-
1
alias_method :owned?, :show?
-
1
alias_method :everything?, :show?
-
1
alias_method :list?, :show?
-
-
1
def create?
-
3
return false unless record.project.is_package
-
3
return false unless ProjectPolicy.new(user, record.project).write?
-
3
record.build_for_platform.blank? || PlatformPolicy.new(user, record.build_for_platform).show?
-
end
-
1
alias_method :rerun_tests?, :create?
-
-
1
def dependent_projects?
-
record.save_to_platform.main? && create?
-
end
-
-
1
def publish_into_testing?
-
return false unless record.new_core?
-
return false unless record.can_publish_into_testing?
-
create? || ( record.save_to_platform.main? && publish? )
-
end
-
-
1
def publish?
-
return false unless record.new_core?
-
return false unless record.can_publish?
-
if record.build_published?
-
local_admin?(record.save_to_platform) || record.save_to_repository.members.exists?(id: user.id)
-
else
-
record.save_to_repository.publish_without_qa ?
-
ProjectPolicy.new(user, record.project).write? : local_admin?(record.save_to_platform)
-
end
-
end
-
1
alias_method :update_type?, :publish?
-
-
1
def create_container?
-
return false unless record.new_core?
-
ProjectPolicy.new(user, record.project).write? || local_admin?(record.save_to_platform)
-
end
-
-
1
def reject_publish?
-
record.save_to_repository.publish_without_qa ?
-
ProjectPolicy.new(user, record.project).write? : local_admin?(record.save_to_platform)
-
end
-
-
1
def cancel?
-
ProjectPolicy.new(user, record.project).write?
-
end
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
pa = %i(
-
arch_id
-
auto_create_container
-
auto_publish
-
auto_publish_status
-
build_for_platform_id
-
commit_hash
-
external_nodes
-
include_testing_subrepository
-
project_id
-
project_version
-
save_buildroot
-
save_to_platform_id
-
save_to_repository_id
-
update_type
-
use_cached_chroot
-
use_extra_tests
-
)
-
pa << {
-
include_repos: [],
-
extra_build_lists: [],
-
extra_repositories: [],
-
extra_params: BuildList::EXTRA_PARAMS,
-
}
-
pa
-
end
-
-
1
class Scope < Scope
-
-
1
def read
-
scope.joins(:project).where <<-SQL, { user_id: policy.user.id, user_group_ids: policy.user_group_ids }
-
(
-
build_lists.user_id = :user_id
-
) OR (
-
projects.visibility = 'open'
-
) OR (
-
projects.owner_type = 'User' AND projects.owner_id = :user_id
-
) OR (
-
projects.owner_type = 'Group' AND projects.owner_id IN (:user_group_ids)
-
) OR (
-
projects.id = ANY (
-
ARRAY (
-
SELECT target_id
-
FROM relations
-
INNER JOIN projects ON projects.id = relations.target_id
-
WHERE relations.target_type = 'Project' AND
-
(
-
projects.owner_type = 'User' AND projects.owner_id != :user_id OR
-
projects.owner_type = 'Group' AND projects.owner_id NOT IN (:user_group_ids)
-
) AND (
-
relations.actor_type = 'User' AND relations.actor_id = :user_id OR
-
relations.actor_type = 'Group' AND relations.actor_id IN (:user_group_ids)
-
)
-
)
-
)
-
)
-
SQL
-
end
-
1
alias_method :everything, :read
-
-
1
def related
-
scope.joins(:project).where <<-SQL, { user_id: policy.user.id, user_group_ids: policy.user_group_ids }
-
(
-
build_lists.user_id = :user_id
-
) OR (
-
projects.owner_type = 'User' AND projects.owner_id = :user_id
-
) OR (
-
projects.owner_type = 'Group' AND projects.owner_id IN (:user_group_ids)
-
) OR (
-
projects.id = ANY (
-
ARRAY (
-
SELECT target_id
-
FROM relations
-
INNER JOIN projects ON projects.id = relations.target_id
-
WHERE relations.target_type = 'Project' AND
-
(
-
projects.owner_type = 'User' AND projects.owner_id != :user_id OR
-
projects.owner_type = 'Group' AND projects.owner_id NOT IN (:user_group_ids)
-
) AND (
-
relations.actor_type = 'User' AND relations.actor_id = :user_id OR
-
relations.actor_type = 'Group' AND relations.actor_id IN (:user_group_ids)
-
)
-
)
-
)
-
)
-
SQL
-
end
-
-
1
def owned
-
scope.joins(:project).where(user_id: policy.user)
-
end
-
-
1
def policy
-
@policy ||= Pundit.policy!(user, :build_list)
-
end
-
end
-
-
end
-
1
class CollaboratorPolicy < ApplicationPolicy
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(role actor_id actor_type)
-
end
-
-
end
-
1
class CommentPolicy < ApplicationPolicy
-
-
1
def create?
-
!user.guest? && ProjectPolicy.new(user, record.project).show?
-
end
-
1
alias_method :new_line?, :create?
-
-
1
def update?
-
return false if user.guest?
-
is_admin? || record.user_id == user.id || local_admin?(record.project)
-
end
-
1
alias_method :destroy?, :update?
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(body data)
-
end
-
-
end
-
1
class GroupPolicy < ApplicationPolicy
-
-
1
def index?
-
!user.guest?
-
end
-
1
alias_method :create?, :index?
-
1
alias_method :remove_user?, :index?
-
-
1
def show?
-
true
-
end
-
1
alias_method :projects?, :show?
-
-
1
def reader?
-
!user.guest? && ( is_admin? || local_reader? )
-
end
-
-
1
def write?
-
!user.guest? && ( is_admin? || owner? || local_writer? )
-
end
-
-
1
def update?
-
!user.guest? && ( is_admin? || owner? || local_admin? )
-
end
-
1
alias_method :add_member?, :update?
-
1
alias_method :manage_members?, :update?
-
1
alias_method :members?, :update?
-
1
alias_method :remove_member?, :update?
-
1
alias_method :remove_members?, :update?
-
1
alias_method :update_member?, :update?
-
-
1
def destroy?
-
!user.guest? && ( is_admin? || owner? )
-
end
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
pa = %i(avatar description delete_avatar default_branch)
-
pa << :uname if record.new_record?
-
pa
-
end
-
-
1
class Scope < Scope
-
1
def show
-
scope
-
end
-
end
-
-
end
-
1
class HookPolicy < ApplicationPolicy
-
-
1
def show?
-
ProjectPolicy.new(user, record.project).update?
-
end
-
1
alias_method :read?, :show?
-
1
alias_method :create?, :show?
-
1
alias_method :destroy?, :show?
-
1
alias_method :update?, :show?
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(data name)
-
end
-
-
end
-
1
class InvitePolicy < ApplicationPolicy
-
1
def invites?
-
is_user?
-
end
-
-
1
def create_invite?
-
is_user?
-
end
-
end
-
1
class IssuePolicy < ApplicationPolicy
-
-
1
def index?
-
# record.project.has_issues?
-
true
-
end
-
-
1
def show?
-
return true if record.pull_request.present? # for redirect from a issue to a pull request
-
return false unless record.project.has_issues?
-
ProjectPolicy.new(user, record.project).show?
-
end
-
1
alias_method :create?, :show?
-
1
alias_method :read?, :show?
-
-
1
def update?
-
return false if user.guest?
-
is_admin? || record.user_id == user.id || local_admin?(record.project)
-
end
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
pa = %i(title body)
-
if ProjectPolicy.new(user, record.project).write?
-
pa << :assignee_id
-
pa << { labelings_attributes: %i(id name color label_id _destroy) }
-
pa << { labelings: [] }
-
end
-
pa
-
end
-
-
end
-
1
class KeyPairPolicy < ApplicationPolicy
-
-
1
def create?
-
return false unless record.repository
-
is_admin? || local_admin?(record.repository.platform)
-
end
-
1
alias_method :destroy?, :create?
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(public secret repository_id)
-
end
-
-
end
-
1
class MassBuildPolicy < ApplicationPolicy
-
-
1
def show?
-
is_admin? || PlatformPolicy.new(user, record.save_to_platform).show?
-
end
-
1
alias_method :read?, :show?
-
1
alias_method :get_list?, :show?
-
1
alias_method :show_fail_reason?, :show?
-
1
def create?
-
is_admin? || owner?(record.save_to_platform) || local_admin?(record.save_to_platform)
-
end
-
1
alias_method :publish?, :create?
-
-
1
def cancel?
-
!record.stop_build && create?
-
end
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(
-
arches
-
auto_create_container
-
auto_publish_status
-
build_for_platform_id
-
description
-
external_nodes
-
include_testing_subrepository
-
increase_release_tag
-
projects_list
-
repositories
-
use_cached_chroot
-
use_extra_tests
-
) << {
-
extra_build_lists: [],
-
extra_mass_builds: [],
-
extra_repositories: []
-
}
-
end
-
-
end
-
1
class PlatformPolicy < ApplicationPolicy
-
-
1
def index?
-
!user.guest?
-
end
-
-
1
def allowed?
-
true
-
end
-
1
alias_method :platforms_for_build?, :allowed?
-
-
1
def show?
-
2
return true if is_admin?
-
2
return true unless record.hidden?
-
return true if record.owner == user
-
owner? || local_reader? || user_platform_ids.include?(record.id)
-
end
-
1
alias_method :projects?, :show?
-
1
alias_method :advisories?, :show?
-
1
alias_method :owned?, :show?
-
1
alias_method :read?, :show?
-
1
alias_method :related?, :show?
-
-
1
def members?
-
return true if is_admin?
-
return true unless record.hidden?
-
return true if record.owner == user
-
owner? || local_reader?
-
end
-
-
1
def create?
-
is_admin?
-
end
-
-
1
def update?
-
is_admin? || owner?
-
end
-
1
alias_method :change_visibility?, :update?
-
-
1
def destroy?
-
record.main? && ( is_admin? || owner? )
-
end
-
-
1
def local_admin_manage?
-
is_admin? || owner? || local_admin?
-
end
-
1
alias_method :add_project?, :local_admin_manage?
-
1
alias_method :remove_file?, :local_admin_manage?
-
-
1
def clone?
-
record.main? && is_admin?
-
end
-
1
alias_method :make_clone?, :clone?
-
-
1
def add_member?
-
record.main? && ( is_admin? || owner? || local_admin? )
-
end
-
1
alias_method :regenerate_metadata?, :add_member?
-
1
alias_method :remove_member?, :add_member?
-
1
alias_method :remove_members?, :add_member?
-
-
1
def clear?
-
record.personal? && ( is_admin? || owner? )
-
end
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(
-
admin_id
-
automatic_metadata_regeneration
-
default_branch
-
description
-
distrib_type
-
name
-
owner
-
parent_platform_id
-
platform_type
-
released
-
term
-
visibility
-
) + [
-
platform_arch_settings_attributes: %i(id arch_id platform_id default time_living)
-
]
-
end
-
-
1
class Scope < Scope
-
-
1
def related
-
scope.where <<-SQL, { user_id: policy.user.id, user_group_ids: policy.user_group_ids, platform_ids: related_platform_ids }
-
(
-
platforms.id IN (:platform_ids)
-
) OR (
-
platforms.owner_type = 'User' AND platforms.owner_id = :user_id
-
) OR (
-
platforms.owner_type = 'Group' AND platforms.owner_id IN (:user_group_ids)
-
) OR (
-
platforms.id = ANY (
-
ARRAY (
-
SELECT target_id
-
FROM relations
-
INNER JOIN platforms ON platforms.id = relations.target_id
-
WHERE relations.target_type = 'Platform' AND
-
(
-
platforms.owner_type = 'User' AND platforms.owner_id != :user_id
-
) AND (
-
relations.actor_type = 'User' AND relations.actor_id = :user_id
-
)
-
)
-
)
-
)
-
SQL
-
end
-
-
1
def show
-
scope.where <<-SQL, { user_id: policy.user.id, user_group_ids: policy.user_group_ids, platform_ids: related_platform_ids, visibility: Platform::VISIBILITY_OPEN }
-
(
-
platforms.visibility = :visibility
-
) OR (
-
platforms.id IN (:platform_ids)
-
) OR (
-
platforms.owner_type = 'User' AND platforms.owner_id = :user_id
-
) OR (
-
platforms.owner_type = 'Group' AND platforms.owner_id IN (:user_group_ids)
-
) OR (
-
platforms.id = ANY (
-
ARRAY (
-
SELECT target_id
-
FROM relations
-
INNER JOIN platforms ON platforms.id = relations.target_id
-
WHERE relations.target_type = 'Platform' AND
-
(
-
platforms.owner_type = 'User' AND platforms.owner_id != :user_id
-
) AND (
-
relations.actor_type = 'User' AND relations.actor_id = :user_id
-
)
-
)
-
)
-
)
-
SQL
-
end
-
-
1
protected
-
-
1
def policy
-
@policy ||= Pundit.policy!(user, :platform)
-
end
-
-
1
def related_platform_ids
-
Rails.cache.fetch(['PlatformPolicy::Scope#related_platform_ids', policy.user]) do
-
policy.user.repositories.pluck(:platform_id)
-
end
-
end
-
end
-
-
end
-
1
class ProductBuildListPolicy < ApplicationPolicy
-
-
1
def index?
-
true
-
end
-
-
1
def show?
-
is_admin? || ProductPolicy.new(user, record.product).show?
-
end
-
1
alias_method :log?, :show?
-
1
alias_method :read?, :show?
-
-
1
def create?
-
return false unless record.project && record.product
-
is_admin? || ProjectPolicy.new(user, record.project).write? || ProductPolicy.new(user, record.product).update?
-
end
-
1
alias_method :cancel?, :create?
-
-
1
def update?
-
is_admin? || ProductPolicy.new(user, record.product).update?
-
end
-
-
1
def destroy?
-
is_admin? || ProductPolicy.new(user, record.product).destroy?
-
end
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(
-
base_url
-
branch
-
commit_hash
-
main_script
-
not_delete
-
params
-
product_id
-
product_name
-
project_id
-
project_version
-
status
-
time_living
-
)
-
end
-
-
end
-
1
class ProductPolicy < ApplicationPolicy
-
-
1
def index?
-
record.platform.main?
-
end
-
-
1
def show?
-
is_admin? || PlatformPolicy.new(user, record.platform).show?
-
end
-
1
alias_method :read?, :show?
-
-
1
def create?
-
return false unless record.platform
-
is_admin? || record.platform.main? && ( owner?(record.platform) || local_admin?(record.platform) )
-
end
-
1
alias_method :clone?, :create?
-
1
alias_method :destroy?, :create?
-
1
alias_method :update?, :create?
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(
-
autostart_status
-
description
-
main_script
-
name
-
params
-
platform_id
-
project_id
-
project_version
-
time_living
-
)
-
end
-
-
end
-
1
class ProjectPolicy < ApplicationPolicy
-
-
1
def index?
-
!user.guest?
-
end
-
1
alias_method :autocomplete_project?, :index?
-
1
alias_method :remove_user?, :index?
-
1
alias_method :preview?, :index?
-
-
1
def show?
-
1
return true if is_admin?
-
1
return true if record.public?
-
return true if record.owner == user
-
return true if record.owner.is_a?(Group) && user_group_ids.include?(record.owner_id)
-
local_reader?
-
end
-
1
alias_method :read?, :show?
-
1
alias_method :archive?, :show?
-
1
alias_method :get_sha1_of_archive?, :show?
-
1
alias_method :get_id?, :show?
-
1
alias_method :refs_list?, :show?
-
-
1
def fork?
-
!user.guest? && show?
-
end
-
-
1
def create?
-
return false if user.guest?
-
return true if is_admin?
-
record.is_a?(Symbol) || owner_policy.write?
-
end
-
-
1
def update?
-
return false if user.guest?
-
is_admin? || owner? || local_admin?
-
end
-
1
alias_method :add_member?, :update?
-
1
alias_method :alias?, :update?
-
1
alias_method :autocomplete_maintainers?, :update?
-
1
alias_method :manage_collaborators?, :update?
-
1
alias_method :members?, :update?
-
1
alias_method :remove_member?, :update?
-
1
alias_method :remove_members?, :update?
-
1
alias_method :schedule?, :update?
-
1
alias_method :sections?, :update?
-
1
alias_method :update_member?, :update?
-
-
1
def destroy?
-
return false if user.guest?
-
is_admin? || owner? || record.owner.is_a?(Group) && record.owner.actors.exists?(actor_type: 'User', actor_id: user.id, role: 'admin')
-
end
-
-
1
def mass_import?
-
return false if user.guest?
-
is_admin? || user.platforms.main.find{ |p| local_admin?(p) }.present?
-
end
-
-
1
def run_mass_import?
-
return true if is_admin?
-
return false unless owner_policy.write?
-
repo = Repository.find(record.add_to_repository_id)
-
repo.platform.main? && PlatformPolicy.new(user, repo.platform).add_project?
-
end
-
-
# for grack
-
1
def write?
-
3
return false if user.guest?
-
3
is_admin? || owner? || local_writer?
-
end
-
-
1
def possible_forks?
-
true
-
end
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(
-
add_to_repository_id
-
architecture_dependent
-
autostart_status
-
default_branch
-
description
-
has_issues
-
has_wiki
-
is_package
-
maintainer_id
-
mass_import
-
name
-
publish_i686_into_x86_64
-
srpm
-
srpms_list
-
url
-
visibility
-
)
-
end
-
-
1
class Scope < Scope
-
-
1
def membered
-
scope.where <<-SQL, { user_id: policy.user.id, user_group_ids: policy.user_group_ids }
-
(
-
projects.owner_type = 'User' AND projects.owner_id = :user_id
-
) OR (
-
projects.owner_type = 'Group' AND projects.owner_id IN (:user_group_ids)
-
) OR (
-
projects.id = ANY (
-
ARRAY (
-
SELECT target_id
-
FROM relations
-
INNER JOIN projects ON projects.id = relations.target_id
-
WHERE relations.target_type = 'Project' AND
-
(
-
projects.owner_type = 'User' AND projects.owner_id != :user_id OR
-
projects.owner_type = 'Group' AND projects.owner_id NOT IN (:user_group_ids)
-
) AND (
-
relations.actor_type = 'User' AND relations.actor_id = :user_id OR
-
relations.actor_type = 'Group' AND relations.actor_id IN (:user_group_ids)
-
)
-
)
-
)
-
)
-
SQL
-
end
-
-
1
def read
-
scope.where <<-SQL, { user_id: policy.user.id, user_group_ids: policy.user_group_ids }
-
(
-
projects.visibility = 'open'
-
) OR (
-
projects.owner_type = 'User' AND projects.owner_id = :user_id
-
) OR (
-
projects.owner_type = 'Group' AND projects.owner_id IN (:user_group_ids)
-
) OR (
-
projects.id = ANY (
-
ARRAY (
-
SELECT target_id
-
FROM relations
-
INNER JOIN projects ON projects.id = relations.target_id
-
WHERE relations.target_type = 'Project' AND
-
(
-
projects.owner_type = 'User' AND projects.owner_id != :user_id OR
-
projects.owner_type = 'Group' AND projects.owner_id NOT IN (:user_group_ids)
-
) AND (
-
relations.actor_type = 'User' AND relations.actor_id = :user_id OR
-
relations.actor_type = 'Group' AND relations.actor_id IN (:user_group_ids)
-
)
-
)
-
)
-
)
-
SQL
-
end
-
1
alias_method :show, :read
-
-
1
protected
-
-
1
def policy
-
@policy ||= Pundit.policy!(user, :project)
-
end
-
end
-
-
1
private
-
-
1
def owner_policy
-
if record.owner.is_a?(User)
-
UserPolicy.new(user, record.owner)
-
else
-
GroupPolicy.new(user, record.owner)
-
end
-
end
-
-
end
-
1
class PullRequestPolicy < ApplicationPolicy
-
-
1
def index?
-
true
-
end
-
-
1
def show?
-
is_admin? || ProjectPolicy.new(user, record.to_project).show?
-
end
-
1
alias_method :read?, :show?
-
1
alias_method :commits?, :show?
-
1
alias_method :files?, :show?
-
1
alias_method :create?, :show?
-
-
1
def update?
-
return false if user.guest?
-
is_admin? || record.user_id == user.id || local_writer?(record.to_project)
-
end
-
-
1
def merge?
-
return false if user.guest?
-
is_admin? || local_writer?(record.to_project)
-
end
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(
-
body
-
from_ref
-
title
-
to_ref
-
) + [ issue_attributes: %i(title body) ]
-
end
-
-
end
-
1
class RepositoryPolicy < ApplicationPolicy
-
-
1
def show?
-
is_admin? || PlatformPolicy.new(user, record.platform).show?
-
end
-
1
alias_method :projects?, :show?
-
1
alias_method :projects_list?, :show?
-
1
alias_method :read?, :show?
-
1
alias_method :public_key?, :show?
-
-
1
def reader?
-
is_admin? || local_reader?(record.platform)
-
end
-
-
1
def write?
-
is_admin? || local_writer?(record.platform)
-
end
-
-
1
def update?
-
is_admin? || local_admin?(record.platform)
-
end
-
1
alias_method :manage_members?, :update?
-
1
alias_method :regenerate_metadata?, :update?
-
1
alias_method :signatures?, :update?
-
-
1
def create?
-
return false if record.platform.personal? && record.name == 'main'
-
is_admin? || owner?(record.platform) || local_admin?(record.platform)
-
end
-
1
alias_method :destroy?, :create?
-
-
1
def packages?
-
record.platform.main? && ( is_admin? || local_admin?(record.platform) )
-
end
-
1
alias_method :remove_member?, :packages?
-
1
alias_method :remove_members?, :packages?
-
1
alias_method :add_member?, :packages?
-
1
alias_method :sync_lock_file?, :packages?
-
-
1
def add_project?
-
is_admin? || local_admin?(record.platform) || repository_user_ids.include?(user.id)
-
end
-
1
alias_method :remove_project?, :add_project?
-
-
1
def settings?
-
is_admin? || owner?(record.platform) || local_admin?(record.platform)
-
end
-
-
1
def key_pair?
-
user.system?
-
end
-
-
1
def add_repo_lock_file?
-
is_admin? || user.system? || ( record.platform.main? && local_admin?(record.platform) )
-
end
-
1
alias_method :remove_repo_lock_file?, :add_repo_lock_file?
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(
-
name
-
description
-
publish_without_qa
-
synchronizing_publications
-
publish_builds_only_from_branch
-
build_for_platform_id
-
resign_rpms
-
)
-
end
-
-
1
private
-
-
# Public: Get user ids of repository.
-
#
-
# Returns the Set of user ids.
-
1
def repository_user_ids
-
Rails.cache.fetch(['RepositoryPolicy#repository_user_ids', record]) do
-
Set.new record.member_ids
-
end
-
end
-
-
end
-
1
class SearchPolicy < ApplicationPolicy
-
-
1
def index?
-
APP_CONFIG['anonymous_access'] || !user.guest?
-
end
-
-
end
-
1
class SettingsNotifierPolicy < ApplicationPolicy
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(
-
can_notify
-
update_code
-
new_comment_commit_owner
-
new_comment_commit_repo_owner
-
new_comment_commit_commentor
-
new_comment
-
new_comment_reply
-
new_issue
-
issue_assign
-
new_build
-
new_associated_build
-
)
-
end
-
-
end
-
1
class SshKeyPolicy < ApplicationPolicy
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(key name)
-
end
-
-
end
-
1
class StatisticPolicy < ApplicationPolicy
-
-
1
def index?
-
true
-
end
-
-
end
-
1
class SubscribePolicy < ApplicationPolicy
-
-
1
def create?
-
return false if user.guest?
-
return true if record.subscribeable.is_a?(Grit::Commit)
-
!record.subscribeable.subscribes.exists?(user_id: user.id)
-
end
-
-
1
def destroy?
-
return false if user.guest?
-
return true if record.subscribeable.is_a?(Grit::Commit)
-
record.subscribeable.subscribes.exists?(user_id: user.id)
-
end
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(status user_id)
-
end
-
-
end
-
1
class TokenPolicy < ApplicationPolicy
-
-
1
def show?
-
# local_admin?(record.subject)
-
is_admin? || owner?(record.subject) || local_admin?(record.subject)
-
end
-
1
alias_method :create?, :show?
-
1
alias_method :read?, :show?
-
1
alias_method :withdraw?, :show?
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(description)
-
end
-
-
end
-
1
class UserBuildsSettingPolicy < ApplicationPolicy
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(external_nodes) + [platforms: []]
-
end
-
-
end
-
1
class UserPolicy < ApplicationPolicy
-
-
1
def show?
-
true
-
end
-
-
1
def update?
-
is_admin? || record == user
-
end
-
1
alias_method :notifiers?, :update?
-
1
alias_method :show_current_user?, :update?
-
1
alias_method :write?, :update?
-
-
1
def tokens?
-
user.role == 'system'
-
end
-
-
# Public: Get list of parameters that the user is allowed to alter.
-
#
-
# Returns Array
-
1
def permitted_attributes
-
%i(
-
avatar
-
company
-
current_password
-
delete_avatar
-
email
-
hide_email
-
language
-
location
-
login
-
name
-
password
-
password_confirmation
-
professional_experience
-
remember_me
-
site
-
sound_notifications
-
uname
-
)
-
end
-
-
1
class Scope < Scope
-
1
def show
-
scope
-
end
-
end
-
-
end
-
1
class AbfWorkerStatusPresenter < ApplicationPresenter
-
-
1
def initialize
-
end
-
-
1
def projects_status
-
Rails.cache.fetch([AbfWorkerStatusPresenter, :projects_status], expires_in: 10.seconds) do
-
result = get_status(:rpm, :publish) { |w, worker| w.to_s =~ /#{worker}_worker_default/ }
-
nodes = RpmBuildNode.total_statistics
-
result[:rpm][:workers] += nodes[:systems]
-
result[:rpm][:build_tasks] += nodes[:busy]
-
result[:rpm][:other_workers] = nodes[:others]
-
-
external_bls = BuildList.for_status(BuildList::BUILD_PENDING).where(mass_build_id: nil).count
-
result[:rpm][:default_tasks] = external_bls
-
-
mass_build_tasks = BuildList.for_status(BuildList::BUILD_PENDING).where.not(mass_build_id: nil).count
-
result[:rpm][:low_tasks] = mass_build_tasks
-
result[:rpm][:tasks] += external_bls + mass_build_tasks
-
result
-
end
-
end
-
-
1
def products_status
-
get_status(:iso) { |w, worker|
-
str = w.to_s
-
str =~ /iso_worker/ && str !~ /observer/
-
}
-
end
-
-
1
protected
-
-
1
def get_status(*queues)
-
status = {}
-
queues.each do |worker|
-
workers = Resque.workers.select{ |w| yield w, worker }
-
status[worker] = status_of_worker workers, worker
-
end
-
status
-
end
-
-
1
def status_of_worker(workers, worker)
-
key = "resque:queue:#{worker}_worker"
-
default_tasks, tasks = Redis.current.llen("#{key}_default"), Redis.current.llen(key)
-
{
-
workers: workers.count,
-
build_tasks: workers.select{ |w| w.working? }.count,
-
default_tasks: default_tasks,
-
low_tasks: tasks,
-
tasks: (default_tasks + tasks)
-
}
-
end
-
end
-
1
require 'csv'
-
1
class Api::V1::RepositoryPackagePresenter < ApplicationPresenter
-
CSV_HEADERS = {
-
1
project_owner: 'Project owner',
-
project_name: 'Project name',
-
package_name: 'Package name',
-
epoch: 'Epoch',
-
version: 'Version',
-
release: 'Release',
-
maintainer_uname: 'Maintainer uname',
-
maintainer_email: 'Maintainer email',
-
committer_uname: 'Committer uname',
-
committer_email: 'Committer email'
-
}
-
-
1
attr_reader :package
-
1
delegate *%i(project name epoch version release assignee build_list), to: :package
-
-
1
def initialize(package)
-
@package = package
-
end
-
-
1
def to_csv_row
-
commit = project.repo.commit(build_list.commit_hash)
-
committer = User.where(email: commit.committer.email).first || commit.committer if commit
-
if committer.is_a? User
-
committer_uname, committer_email = committer.uname, committer.email
-
elsif committer.is_a? Grit::Actor
-
committer_uname, committer_email = committer.name, committer.email
-
end
-
CSV::Row.new(
-
CSV_HEADERS.keys,
-
[
-
project.owner_uname,
-
project.name,
-
name,
-
epoch,
-
version,
-
release,
-
assignee.uname,
-
assignee.email,
-
committer_uname,
-
committer_email
-
]
-
)
-
end
-
-
1
def self.csv_header
-
# Using ruby's built-in CSV::Row class
-
# true - means its a header
-
CSV::Row.new CSV_HEADERS.keys, CSV_HEADERS.values, true
-
end
-
-
end
-
1
class ApplicationPresenter < RosaPresenter::Base
-
end
-
-
#class ApplicationPresenter
-
# include ActionDispatch::Routing::UrlFor
-
# include ActionView::Helpers::UrlHelper
-
# include Rails.application.routes.url_helpers
-
#
-
# attr_accessor :controller
-
#
-
# def initialize(item, opts)
-
# end
-
#
-
# # TODO it needs to be refactored!
-
# class << self
-
# def present(item, opts, &block)
-
# block.call(self.new(item, opts))
-
# end
-
#
-
# def present_collection(collection, &block)
-
# res = collection.map {|e| self.new(*e)}
-
# if block.present?
-
# res = res.inject('') do |akk, presenter|
-
# akk << block.call(presenter)
-
# akk
-
# end
-
# end
-
# return res
-
# end
-
# end
-
#
-
# protected
-
#
-
# def t(*args)
-
# I18n.translate(*args)
-
# end
-
#
-
# def l(*args)
-
# I18n.localize(*args)
-
# end
-
#end
-
#
-
#module Presenters
-
# module Activation
-
# def self.included(klass) # :nodoc:
-
# klass.prepend_before_filter :activate_presenter
-
# end
-
#
-
# private
-
# def activate_presenter
-
# ApplicationPresenter.controller = self
-
# end
-
# end
-
#end
-
#ActionController::Base.send(:include, Presenters::Activation)
-
1
class CommentPresenter < ApplicationPresenter
-
1
include PullRequestHelper
-
-
1
attr_accessor :comment, :options
-
1
attr_reader :header, :image, :date, :caption, :content, :buttons, :is_reference_to_issue,
-
:reference_project
-
-
1
def initialize(comment, opts = {})
-
@is_reference_to_issue = !!(comment.automatic && comment.created_from_issue_id) # is it reference issue from another issue
-
@comment, @user, @options = comment, comment.user, opts
-
-
unless @is_reference_to_issue
-
@content = @comment.body
-
else
-
issue = Issue.where(id: comment.created_from_issue_id).first
-
if issue && (comment.data[:comment_id].nil? || Comment.exists?(comment.data[:comment_id]))
-
@referenced_issue = issue.pull_request || issue
-
@reference_project = issue.project
-
title = if issue == opts[:commentable]
-
"#{issue.serial_id}"
-
elsif issue.project.owner == opts[:commentable].project.owner
-
"#{issue.project.name}##{issue.serial_id}"
-
else
-
"#{issue.project.name_with_owner}##{issue.serial_id}"
-
end
-
title = "<span style=\"color: #777;\">#{title}</span>:"
-
issue_link = project_issue_path(issue.project, issue)
-
@content = "<a href=\"#{issue_link}\">#{title} #{issue.title}</a>".html_safe
-
else
-
@content = t 'layout.comments.removed'
-
end
-
end
-
end
-
-
1
def expandable?
-
false
-
end
-
-
1
def buttons?
-
!@is_reference_to_issue # dont show for automatic comment
-
end
-
-
1
def content?
-
true
-
end
-
-
1
def caption?
-
false
-
end
-
-
1
def issue_referenced_state?
-
@referenced_issue # show state of the existing referenced issue
-
end
-
-
1
def buttons
-
project, commentable = options[:project], options[:commentable]
-
-
link_to_comment = "#{helpers.project_commentable_path(project, commentable)}##{comment_anchor}"
-
klass = "#{@options[:in_discussion].present? ? 'in_discussion_' : ''}link_to_comment"
-
res = [ link_to(content_tag(:i, nil, class: 'fa fa-link'),
-
link_to_comment,
-
class: klass).html_safe ]
-
if controller.policy(@comment).update?
-
res << link_to(content_tag(:i, nil, class: 'fa fa-edit'),
-
"#update-comment#{comment.id}",
-
'ng-click' => "commentsCtrl.toggleEditForm(#{comment_id})" ).html_safe
-
end
-
if controller.policy(@comment).destroy?
-
res << link_to(content_tag(:i, nil, class: 'fa fa-close'),
-
'',
-
'ng-click' => "commentsCtrl.remove(#{comment_id})").html_safe
-
end
-
res
-
end
-
-
1
def header
-
user_link = link_to @user.fullname, user_path(@user.uname)
-
res = unless @is_reference_to_issue
-
"#{user_link} #{t 'layout.comments.has_commented'}"
-
else
-
t 'layout.comments.reference', user: user_link
-
end
-
res.html_safe
-
end
-
-
1
def image
-
@image ||= helpers.avatar_url(@user, :medium)
-
end
-
-
1
def date
-
@date ||= @comment.created_at
-
end
-
-
1
def comment_id?
-
true
-
end
-
-
1
def comment_id
-
@comment.id
-
end
-
-
1
def comment_anchor
-
# check for pull diff inline comment
-
before = if @options[:add_anchor].present? && !@options[:in_discussion]
-
'diff-'
-
else
-
''
-
end
-
"#{before}comment#{@comment.id}"
-
end
-
-
1
def issue_referenced_state
-
if @referenced_issue.is_a? Issue
-
statuses = {'open' => 'success', 'closed' => 'danger'}
-
content_tag :span, t("layout.issues.status.#{@referenced_issue.status}"), class: "pull-right label label-#{statuses[@referenced_issue.status]}"
-
else
-
pull_status_label @referenced_issue.status, class: 'pull-right'
-
end.html_safe
-
end
-
end
-
1
class GitPresenters::CommitAsMessagePresenter < ApplicationPresenter
-
1
include CommitHelper
-
-
1
attr_accessor :commit
-
1
attr_reader :header, :image, :date, :caption, :content, :expandable,
-
:is_reference_to_issue, :committer
-
-
1
def initialize(commit, opts = {})
-
comment = opts[:comment]
-
@is_reference_to_issue = !!comment # is it reference issue from commit
-
@project = if comment
-
Project.where(id: comment.data[:from_project_id]).first
-
else
-
opts[:project]
-
end
-
commit = commit || @project.repo.commit(Comment.hex_to_commit_hash comment.created_from_commit_hash) if @project
-
-
if @project && commit
-
@committer = User.where(email: commit.committer.email).first || commit.committer
-
@commit_hash = commit.id
-
@committed_date, @authored_date = commit.committed_date, commit.authored_date
-
@commit_message = commit.message
-
else
-
@committer = t('layout.commits.unknown_committer')
-
@commit_hash = Comment.hex_to_commit_hash comment.created_from_commit_hash
-
@committed_date = @authored_date = comment.created_at
-
@commit_message = t('layout.commits.deleted')
-
end
-
prepare_message
-
end
-
-
1
def header
-
@header ||= if @is_reference_to_issue
-
I18n.t('layout.commits.reference', committer: committer_link, commit: commit_link)
-
elsif @project.present?
-
I18n.t('layout.messages.commits.header',
-
committer: committer_link, commit: commit_link, project: @project.name)
-
end.html_safe
-
end
-
-
1
def image
-
@image ||= if committer.is_a? User
-
helpers.avatar_url(committer, :medium)
-
elsif committer.is_a? Grit::Actor
-
helpers.avatar_url_by_email(committer.email, :medium)
-
else
-
helpers.gravatar_url('Unknown', User::AVATAR_SIZES[:medium])
-
end
-
end
-
-
1
def date
-
@date ||= @committed_date || @authored_date
-
end
-
-
1
def expandable?
-
true
-
end
-
-
1
def buttons?
-
false
-
end
-
-
1
def content?
-
content.present?
-
end
-
-
1
def caption?
-
true
-
end
-
-
1
def comment_id?
-
false
-
end
-
-
1
def issue_referenced_state?
-
false
-
end
-
-
1
def reference_project
-
@project if @is_reference_to_issue
-
end
-
-
1
protected
-
-
1
def committer_link
-
@committer_link ||= if committer.is_a? User
-
link_to committer.uname, user_path(committer)
-
elsif committer.is_a?(Grit::Actor) && committer.email.present?
-
mail_to committer.email, committer.name
-
else # unknown committer
-
committer
-
end
-
end
-
-
1
def commit_link
-
if @project
-
link_to shortest_hash_id(@commit_hash), commit_path(@project, @commit_hash)
-
else
-
shortest_hash_id(@commit_hash)
-
end
-
end
-
-
1
def prepare_message
-
(@caption, @content) = @commit_message.split("\n\n", 2)
-
@caption = 'empty message' unless @caption.present?
-
if @caption.length > 72
-
tmp = '...' + @caption[69..-1]
-
@content = (@content.present?) ? tmp + @content : tmp
-
@caption = @caption[0..68] + '...'
-
end
-
end
-
end
-
1
class StatisticPresenter < ApplicationPresenter
-
-
1
attr_accessor :range_start, :range_end, :unit, :users_or_groups
-
-
1
def initialize(range_start: nil, range_end: nil, unit: nil, users_or_groups: nil)
-
@range_start = range_start
-
@range_end = range_end
-
@unit = unit
-
@users_or_groups = users_or_groups.to_s.split(/,/).map(&:strip).select(&:present?).first(3)
-
end
-
-
1
def as_json(options = nil)
-
{
-
build_lists: {
-
build_started: prepare_collection(build_lists_started),
-
success: prepare_collection(build_lists_success),
-
build_error: prepare_collection(build_lists_error),
-
build_published: prepare_collection(build_lists_published),
-
-
build_started_count: build_lists_started.sum(&:count),
-
success_count: build_lists_success.sum(&:count),
-
build_error_count: build_lists_error.sum(&:count),
-
build_published_count: build_lists_published.sum(&:count),
-
},
-
commits: {
-
chart: prepare_collection(commits_chart),
-
commits_count: commits_chart.sum(&:count)
-
},
-
issues: {
-
open: prepare_collection(issues_open),
-
reopen: prepare_collection(issues_reopen),
-
closed: prepare_collection(issues_closed),
-
-
open_count: issues_open.sum(&:count),
-
reopen_count: issues_reopen.sum(&:count),
-
closed_count: issues_closed.sum(&:count)
-
},
-
pull_requests: {
-
open: prepare_collection(pull_requests_open),
-
merged: prepare_collection(pull_requests_merged),
-
closed: prepare_collection(pull_requests_closed),
-
-
open_count: pull_requests_open.sum(&:count),
-
merged_count: pull_requests_merged.sum(&:count),
-
closed_count: pull_requests_closed.sum(&:count)
-
}
-
}
-
end
-
-
1
private
-
-
1
def user_ids
-
@user_ids ||= User.where(uname: users_or_groups).pluck(:id)
-
end
-
-
1
def group_ids
-
@group_ids ||= Group.where(uname: users_or_groups).pluck(:id)
-
end
-
-
1
def scope
-
@scope ||= Statistic.for_period(range_start, range_end).
-
for_users(user_ids).for_groups(group_ids).
-
select("SUM(counter) as count, date_trunc('#{ unit }', activity_at) as activity_at").
-
group("date_trunc('#{ unit }', activity_at)").order('activity_at')
-
end
-
-
1
def issues_open
-
@issues_open ||= scope.issues_open.to_a
-
end
-
-
1
def issues_reopen
-
@issues_reopen ||= scope.issues_reopen.to_a
-
end
-
-
1
def issues_closed
-
@issues_closed ||= scope.issues_closed.to_a
-
end
-
-
1
def pull_requests_open
-
@pull_requests_open ||= scope.pull_requests_open.to_a
-
end
-
-
1
def pull_requests_merged
-
@pull_requests_merged ||= scope.pull_requests_merged.to_a
-
end
-
-
1
def pull_requests_closed
-
@pull_requests_closed ||= scope.pull_requests_closed.to_a
-
end
-
-
1
def commits_chart
-
@commits_chart ||= scope.commits.to_a
-
end
-
-
1
def build_lists_started
-
@build_lists_started ||= scope.build_lists_started.to_a
-
end
-
-
1
def build_lists_success
-
@build_lists_success ||= scope.build_lists_success.to_a
-
end
-
-
1
def build_lists_error
-
@build_lists_error ||= scope.build_lists_error.to_a
-
end
-
-
1
def build_lists_published
-
@build_lists_published ||= scope.build_lists_published.to_a
-
end
-
-
1
def prepare_collection(items)
-
data = []
-
to = range_start
-
while to <= range_end
-
from = to - 1.send(unit)
-
y = items.find{ |i| i.activity_at > from && i.activity_at <= to }.try(:count)
-
data << { x: to.strftime(format), y: y || 0 }
-
to += 1.send(unit)
-
end
-
data
-
end
-
-
1
def format
-
@format ||= unit == :hour ? '%H:%M' : '%Y-%m-%d'
-
end
-
-
end
-
1
module AbfWorkerService
-
1
class Base
-
-
1
REDIS_MAIN_KEY = 'abf-worker::build-lists-publish-task-manager::'
-
-
%w(
-
1
PROJECTS_FOR_CLEANUP
-
LOCKED_PROJECTS_FOR_CLEANUP
-
LOCKED_BUILD_LISTS
-
PACKAGES_FOR_CLEANUP
-
REP_AND_PLS_OF_BUILD_LISTS_FOR_CLEANUP_FROM_TESTING
-
BUILD_LISTS_FOR_CLEANUP_FROM_TESTING
-
).each do |kind|
-
6
const_set kind, "#{REDIS_MAIN_KEY}#{kind.downcase.gsub('_', '-')}"
-
end
-
-
1
def self.cleanup_completed(projects_for_cleanup)
-
projects_for_cleanup.each do |key|
-
Redis.current.lrem LOCKED_PROJECTS_FOR_CLEANUP, 0, key
-
Redis.current.hdel PACKAGES_FOR_CLEANUP, key
-
end
-
end
-
-
1
def self.cleanup_failed(projects_for_cleanup)
-
projects_for_cleanup.each do |key|
-
Redis.current.lrem LOCKED_PROJECTS_FOR_CLEANUP, 0, key
-
Redis.current.lpush PROJECTS_FOR_CLEANUP, key
-
end
-
end
-
-
1
def self.cleanup_packages_from_testing(platform_id, repository_id, *build_lists)
-
return if build_lists.blank?
-
rep_pl = "#{repository_id}-#{platform_id}"
-
key = "#{BUILD_LISTS_FOR_CLEANUP_FROM_TESTING}-#{rep_pl}"
-
Redis.current.sadd REP_AND_PLS_OF_BUILD_LISTS_FOR_CLEANUP_FROM_TESTING, rep_pl
-
Redis.current.sadd key, build_lists
-
end
-
-
1
def self.unlock_build_list(build_list)
-
Redis.current.lrem LOCKED_BUILD_LISTS, 0, build_list.id
-
end
-
-
1
protected
-
-
1
def packages_structure
-
structure = {sources: [], binaries: {}}
-
Arch.pluck(:name).each{ |name| structure[:binaries][name.to_sym] = [] }
-
structure
-
end
-
-
1
def fill_packages(bl, results_map, field = :sha1)
-
results_map[:sources] |= bl.packages.by_package_type('source').pluck(field).compact if field != :sha1
-
-
binaries = bl.packages.by_package_type('binary').pluck(field).compact
-
arch = bl.arch.name.to_sym
-
results_map[:binaries][arch] |= binaries
-
# Publish/remove i686 RHEL packages into/from x86_64
-
if arch == :i586 && bl.build_for_platform.distrib_type == 'rhel' && bl.project.publish_i686_into_x86_64?
-
results_map[:binaries][:x86_64] |= binaries
-
end
-
end
-
-
1
def filter_build_lists_without_packages(*build_lists)
-
ids = []
-
build_lists = build_lists.flatten.select do |build_list|
-
sha1 = build_list.packages.pluck(:sha1).find do |sha1|
-
!FileStoreService::File.new(sha1: sha1).exist?
-
end
-
if sha1.present?
-
ids << build_list.id
-
false
-
else
-
true
-
end
-
end
-
-
BuildList.where(id: ids).update_all(status: BuildList::PACKAGES_FAIL)
-
-
build_lists
-
end
-
-
end
-
end
-
1
module AbfWorkerService
-
1
class Container < Base
-
-
1
attr_accessor :build_list
-
-
1
def initialize(build_list)
-
@build_list = build_list
-
end
-
-
1
def create!
-
cleanup_folder
-
-
if filter_build_lists_without_packages(build_list).blank?
-
build_list.fail_publish_container
-
return
-
end
-
-
Resque.push(
-
'publish_worker', # Low priority
-
'class' => 'AbfWorker::PublishWorker',
-
'args' => [{
-
id: build_list.id,
-
cmd_params: cmd_params,
-
main_script: 'build.sh',
-
rollback_script: 'rollback.sh',
-
platform: {
-
platform_path: platform_path,
-
type: distrib_type,
-
name: build_list.build_for_platform.name,
-
arch: build_list.arch.name
-
},
-
repository: {id: build_list.save_to_repository_id},
-
time_living: 9600, # 160 min
-
packages: packages,
-
old_packages: packages_structure,
-
build_list_ids: [build_list.id],
-
projects_for_cleanup: [],
-
extra: {create_container: true}
-
}]
-
)
-
end
-
-
1
def destroy!
-
system "rm -rf #{platform_path}"
-
end
-
-
1
protected
-
-
1
def cmd_params
-
{
-
'RELEASED' => false,
-
'REPOSITORY_NAME' => build_list.save_to_repository.name,
-
'TYPE' => distrib_type,
-
'IS_CONTAINER' => true,
-
'ID' => build_list.id,
-
'SAVE_TO_PLATFORM' => build_list.save_to_platform.name,
-
'BUILD_FOR_PLATFORM' => build_list.build_for_platform.name,
-
'FILE_STORE_ADDR' => APP_CONFIG['file_store_url']
-
}.map{ |k, v| "#{k}=#{v}" }.join(' ')
-
end
-
-
1
def cleanup_folder
-
system "rm -rf #{platform_path} && mkdir -p #{platform_path}"
-
end
-
-
1
def platform_path
-
@platform_path ||= "#{build_list.save_to_platform.path}/container/#{build_list.id}"
-
end
-
-
1
def distrib_type
-
@distrib_type ||= build_list.build_for_platform.distrib_type
-
end
-
-
1
def packages
-
structure = packages_structure
-
structure[:sources] = build_list.packages.by_package_type('source').pluck(:sha1).compact
-
structure[:binaries][build_list.arch.name.to_sym] = build_list.packages.by_package_type('binary').pluck(:sha1).compact
-
structure
-
end
-
-
end
-
end
-
1
module AbfWorkerService
-
1
class PlatformMetadata < Base
-
-
1
attr_accessor :platform
-
-
1
def initialize(platform)
-
@platform = platform
-
end
-
-
1
def regenerate!
-
return unless can_regenerate?
-
-
Resque.push(
-
'publish_worker_default',
-
'class' => 'AbfWorker::PublishWorkerDefault',
-
'args' => [{
-
id: Time.now.to_i,
-
cmd_params: cmd_params,
-
main_script: 'regenerate_platform_metadata.sh',
-
platform: {
-
platform_path: "#{platform.path}/repository",
-
type: platform.distrib_type,
-
name: platform.name,
-
arch: 'x86_64'
-
},
-
time_living: 9600, # 160 min
-
extra: {platform_id: platform.id, regenerate_platform: true}
-
}]
-
) if platform.start_regeneration
-
end
-
-
1
protected
-
-
1
def can_regenerate?
-
repos = platform.repositories
-
return false if repos.find{ |r| r.repo_lock_file_exists? }
-
-
statuses = RepositoryStatus.where(platform_id: platform.id)
-
return true if statuses.blank?
-
-
statuses = statuses.map do |s|
-
s.ready? || s.can_start_regeneration? || s.can_start_resign?
-
end.uniq
-
statuses == [true]
-
end
-
-
1
def cmd_params
-
{
-
'RELEASED' => platform.released,
-
'REPOSITORY_NAMES' => platform.repositories.map(&:name).join(','),
-
'TYPE' => platform.distrib_type,
-
'REGENERATE_PLATFORM_METADATA' => true,
-
'SAVE_TO_PLATFORM' => platform.name,
-
'BUILD_FOR_PLATFORM' => platform.name,
-
'FILE_STORE_ADDR' => APP_CONFIG['file_store_url']
-
}.map{ |k, v| "#{k}=#{v}" }.join(' ')
-
end
-
-
end
-
end
-
1
module AbfWorkerService
-
1
class Repository < Base
-
-
1
attr_accessor :repository
-
-
1
def initialize(repository)
-
@repository = repository
-
end
-
-
1
def destroy_project!(project)
-
if repository.platform.personal?
-
Platform.main.each do |main_platform|
-
key = "#{project.id}-#{repository.id}-#{main_platform.id}"
-
Redis.current.lpush PROJECTS_FOR_CLEANUP, key
-
gather_old_packages project.id, repository.id, main_platform.id
-
-
Redis.current.lpush PROJECTS_FOR_CLEANUP, ('testing-' << key)
-
gather_old_packages project.id, repository.id, main_platform.id, true
-
end
-
else
-
key = "#{project.id}-#{repository.id}-#{repository.platform_id}"
-
Redis.current.lpush PROJECTS_FOR_CLEANUP, key
-
gather_old_packages project.id, repository.id, repository.platform_id
-
-
Redis.current.lpush PROJECTS_FOR_CLEANUP, ('testing-' << key)
-
gather_old_packages project.id, repository.id, repository.platform_id, true
-
end
-
end
-
-
1
def resign!(repository_status)
-
return if repository.repo_lock_file_exists?
-
-
Resque.push(
-
'publish_worker_default',
-
'class' => "AbfWorker::PublishWorkerDefault",
-
'args' => [{
-
id: repository.id,
-
cmd_params: cmd_params,
-
main_script: 'resign.sh',
-
platform: {
-
platform_path: "#{repository.platform.path}/repository",
-
type: distrib_type,
-
name: repository.platform.name,
-
arch: 'x86_64'
-
},
-
repository: {id: repository.id},
-
skip_feedback: true,
-
time_living: 9600, # 160 min
-
extra: {repository_status_id: repository_status.id, resign: true}
-
}]
-
) if repository_status.start_resign
-
end
-
-
1
protected
-
-
1
def cmd_params
-
{
-
'RELEASED' => repository.platform.released,
-
'REPOSITORY_NAME' => repository.name,
-
'TYPE' => distrib_type,
-
'FILE_STORE_ADDR' => APP_CONFIG['file_store_url']
-
}.map{ |k, v| "#{k}=#{v}" }.join(' ')
-
end
-
-
1
def distrib_type
-
@distrib_type ||= repository.platform.distrib_type
-
end
-
-
1
def gather_old_packages(project_id, repository_id, platform_id, testing = false)
-
build_lists_for_cleanup = []
-
status = testing ? BuildList::BUILD_PUBLISHED_INTO_TESTING : BuildList::BUILD_PUBLISHED
-
Arch.pluck(:id).each do |arch_id|
-
bl = BuildList.where(project_id: project_id).
-
where(new_core: true, status: status).
-
where(save_to_repository_id: repository_id).
-
where(build_for_platform_id: platform_id).
-
where(arch_id: arch_id).
-
order(:updated_at).first
-
build_lists_for_cleanup << bl if bl
-
end
-
-
old_packages = packages_structure
-
build_lists_for_cleanup.each do |bl|
-
bl.last_published(testing).includes(:packages).limit(2).each do |old_bl|
-
fill_packages(old_bl, old_packages, :fullname)
-
end
-
end
-
key = (testing ? 'testing-' : '') << "#{project_id}-#{repository_id}-#{platform_id}"
-
Redis.current.hset PACKAGES_FOR_CLEANUP, key, old_packages.to_json
-
end
-
-
end
-
end
-
1
module AbfWorkerService
-
1
class RepositoryMetadata < Base
-
-
1
attr_accessor :repository, :repository_status
-
-
1
def initialize(repository_status)
-
@repository_status = repository_status
-
@repository = repository_status.repository
-
end
-
-
1
def regenerate!
-
# Checks mirror sync status
-
return if repository.repo_lock_file_exists?
-
-
platform_path = "#{repository.platform.path}/repository"
-
if repository.platform.personal?
-
platform_path << '/' << build_for_platform.name
-
system "mkdir -p #{platform_path}"
-
end
-
-
Resque.push(
-
'publish_worker_default',
-
'class' => 'AbfWorker::PublishWorkerDefault',
-
'args' => [{
-
id: Time.now.to_i,
-
cmd_params: cmd_params,
-
resign_rpms: @repository_status.resign_rpms,
-
main_script: 'build.sh',
-
rollback_script: 'rollback.sh',
-
platform: {
-
platform_path: platform_path,
-
type: build_for_platform.distrib_type,
-
name: build_for_platform.name,
-
arch: 'x86_64'
-
},
-
repository: {id: repository.id},
-
# time_living: 9600, # 160 min
-
time_living: 14400, # 240 min
-
extra: {repository_status_id: repository_status.id, regenerate: true}
-
}]
-
) if repository_status.start_regeneration
-
-
end
-
-
1
protected
-
-
1
def build_for_platform
-
@build_for_platform ||= repository_status.platform
-
end
-
-
1
def cmd_params
-
{
-
'RELEASED' => repository.platform.released,
-
'REPOSITORY_NAME' => repository.name,
-
'TYPE' => build_for_platform.distrib_type,
-
'REGENERATE_METADATA' => true,
-
'SAVE_TO_PLATFORM' => repository.platform.name,
-
'BUILD_FOR_PLATFORM' => build_for_platform.name,
-
'FILE_STORE_ADDR' => APP_CONFIG['file_store_url']
-
}.map{ |k, v| "#{k}=#{v}" }.join(' ')
-
end
-
-
end
-
end
-
1
module AbfWorkerService
-
1
class Rpm < Base
-
-
1
WORKERS_COUNT = APP_CONFIG['abf_worker']['publish_workers_count']
-
-
1
attr_accessor :save_to_repository_id, :build_for_platform_id, :testing
-
-
1
def initialize(save_to_repository_id, build_for_platform_id, testing)
-
@save_to_repository_id = save_to_repository_id
-
@build_for_platform_id = build_for_platform_id
-
@testing = testing
-
end
-
-
1
def self.publish!
-
build_rpms
-
build_rpms(true)
-
end
-
-
1
def self.build_rpms(testing = false)
-
available_repos = BuildList.
-
select('MIN(updated_at) as min_updated_at, save_to_repository_id, build_for_platform_id').
-
where(new_core: true, status: (testing ? BuildList::BUILD_PUBLISH_INTO_TESTING : BuildList::BUILD_PUBLISH)).
-
group(:save_to_repository_id, :build_for_platform_id).
-
order('min_updated_at ASC').
-
limit(WORKERS_COUNT * 2) # because some repos may be locked
-
-
locked_rep = RepositoryStatus.not_ready.joins(:platform).
-
where(platforms: {platform_type: 'main'}).pluck(:repository_id)
-
available_repos = available_repos.where('save_to_repository_id NOT IN (?)', locked_rep) unless locked_rep.empty?
-
-
for_cleanup = Redis.current.lrange(PROJECTS_FOR_CLEANUP, 0, -1).map do |key|
-
next if testing && key !~ /^testing-/
-
rep, pl = *key.split('-').last(2)
-
locked_rep.present? && locked_rep.include?(rep.to_i) ? nil : [rep.to_i, pl.to_i]
-
end.compact
-
-
for_cleanup_from_testing = Redis.current.smembers(REP_AND_PLS_OF_BUILD_LISTS_FOR_CLEANUP_FROM_TESTING).map do |key|
-
next if Redis.current.scard("#{BUILD_LISTS_FOR_CLEANUP_FROM_TESTING}-#{key}") == 0
-
rep, pl = *key.split('-')
-
locked_rep.present? && locked_rep.include?(rep.to_i) ? nil : [rep.to_i, pl.to_i]
-
end.compact if testing
-
for_cleanup_from_testing ||= []
-
-
counter = 1
-
available_repos = available_repos.map{ |bl| [bl.save_to_repository_id, bl.build_for_platform_id] } | for_cleanup | for_cleanup_from_testing
-
available_repos.each do |save_to_repository_id, build_for_platform_id|
-
next if RepositoryStatus.not_ready.where(repository_id: save_to_repository_id, platform_id: build_for_platform_id).exists?
-
break if counter > WORKERS_COUNT
-
service = AbfWorkerService::Rpm.new(
-
save_to_repository_id,
-
build_for_platform_id,
-
testing
-
)
-
counter += 1 if service.create
-
end
-
end
-
-
1
def create
-
key = "#{save_to_repository_id}-#{build_for_platform_id}"
-
projects_for_cleanup = Redis.current.lrange(PROJECTS_FOR_CLEANUP, 0, -1).select do |k|
-
(testing && k =~ /^testing-[\d]+-#{key}$/) || (!testing && k =~ /^[\d]+-#{key}$/)
-
end
-
-
prepare_build_lists(projects_for_cleanup)
-
-
projects_for_cleanup.each do |key|
-
Redis.current.lrem PROJECTS_FOR_CLEANUP, 0, key
-
packages = Redis.current.hget PACKAGES_FOR_CLEANUP, key
-
next unless packages
-
packages = JSON.parse packages
-
old_packages[:sources] |= packages['sources']
-
Arch.pluck(:name).each do |arch|
-
old_packages[:binaries][arch.to_sym] |= packages['binaries'][arch] || []
-
end
-
end
-
-
if testing
-
build_lists_for_cleanup_from_testing = Redis.current.smembers("#{BUILD_LISTS_FOR_CLEANUP_FROM_TESTING}-#{save_to_repository_id}-#{build_for_platform_id}")
-
BuildList.where(id: build_lists_for_cleanup_from_testing).each do |b|
-
fill_packages(b, old_packages, :fullname)
-
end if build_lists_for_cleanup_from_testing.present?
-
end
-
build_lists_for_cleanup_from_testing ||= []
-
-
bl = build_lists[0]
-
return false if !bl && old_packages[:sources].empty? && old_packages[:binaries].values.flatten.empty?
-
-
# Checks mirror sync status
-
return false if save_to_repository.repo_lock_file_exists? || !save_to_repository.platform.ready?
-
-
repository_status = save_to_repository.repository_statuses.find_or_create_by(platform_id: build_for_platform_id)
-
return false unless repository_status.publish
-
-
options = {
-
id: (bl ? bl.id : Time.now.to_i),
-
cmd_params: cmd_params,
-
main_script: 'build.sh',
-
rollback_script: 'rollback.sh',
-
platform: {
-
platform_path: platform_path,
-
type: distrib_type,
-
name: build_for_platform.name,
-
arch: (bl ? bl.arch.name : 'x86_64')
-
},
-
repository: {id: save_to_repository_id},
-
time_living: 9600, # 160 min
-
extra: {
-
repository_status_id: repository_status.id,
-
build_lists_for_cleanup_from_testing: build_lists_for_cleanup_from_testing
-
}
-
}
-
-
packages, build_list_ids, new_sources = fill_in_packages
-
push(options.merge({
-
packages: packages,
-
old_packages: old_packages,
-
build_list_ids: build_list_ids,
-
projects_for_cleanup: projects_for_cleanup
-
}))
-
lock_projects(projects_for_cleanup)
-
cleanup(build_lists_for_cleanup_from_testing)
-
return true
-
end
-
-
1
protected
-
-
1
def platform_path
-
@platform_path ||= begin
-
path = "#{save_to_platform.path}/repository"
-
if save_to_platform.personal?
-
path << '/' << build_for_platform.name
-
system "mkdir -p #{path}"
-
end
-
path
-
end
-
end
-
-
1
def cmd_params
-
{
-
'RELEASED' => save_to_platform.released,
-
'REPOSITORY_NAME' => save_to_repository.name,
-
'TYPE' => distrib_type,
-
'SAVE_TO_PLATFORM' => save_to_platform.name,
-
'BUILD_FOR_PLATFORM' => build_for_platform.name,
-
'TESTING' => testing,
-
'FILE_STORE_ADDR' => APP_CONFIG['file_store_url']
-
}.map{ |k, v| "#{k}=#{v}" }.join(' ')
-
end
-
-
1
def save_to_repository
-
@save_to_repository ||= ::Repository.find(save_to_repository_id)
-
end
-
-
1
def save_to_platform
-
@save_to_platform ||= save_to_repository.platform
-
end
-
-
1
def build_for_platform
-
@build_for_platform ||= Platform.find(build_for_platform_id)
-
end
-
-
1
def distrib_type
-
@distrib_type ||= build_for_platform.distrib_type
-
end
-
-
1
def old_packages
-
@old_packages ||= packages_structure
-
end
-
-
1
def fill_in_packages
-
packages, build_list_ids, new_sources = packages_structure, [], {}
-
build_lists.each do |bl|
-
# remove duplicates of sources for different arches
-
bl.packages.by_package_type('source').each{ |s| new_sources["#{s.fullname}"] = s.sha1 }
-
fill_packages(bl, packages)
-
bl.last_published(testing).includes(:packages).limit(2).each{ |old_bl|
-
fill_packages(old_bl, old_packages, :fullname)
-
}
-
# TODO: do more flexible
-
# Removes old packages which already in the main repo
-
bl.last_published(false).includes(:packages).limit(3).each{ |old_bl|
-
fill_packages(old_bl, old_packages, :fullname)
-
} if testing
-
build_list_ids << bl.id
-
Redis.current.lpush(LOCKED_BUILD_LISTS, bl.id)
-
end
-
packages[:sources] = new_sources.values.compact
-
-
[packages, build_list_ids, new_sources]
-
end
-
-
1
def lock_projects(projects_for_cleanup)
-
projects_for_cleanup.each do |key|
-
Redis.current.lpush LOCKED_PROJECTS_FOR_CLEANUP, key
-
end
-
end
-
-
1
def cleanup(build_lists_for_cleanup_from_testing)
-
rep_pl = "#{save_to_repository_id}-#{build_for_platform_id}"
-
r_key = "#{BUILD_LISTS_FOR_CLEANUP_FROM_TESTING}-#{rep_pl}"
-
build_lists_for_cleanup_from_testing.each do |key|
-
Redis.current.srem r_key, key
-
end
-
if Redis.current.scard(r_key) == 0
-
Redis.current.srem REP_AND_PLS_OF_BUILD_LISTS_FOR_CLEANUP_FROM_TESTING, rep_pl
-
end
-
end
-
-
1
def push(options)
-
Resque.push(
-
'publish_worker_default',
-
'class' => 'AbfWorker::PublishWorkerDefault',
-
'args' => [options]
-
)
-
end
-
-
1
def prepare_build_lists(projects_for_cleanup)
-
# We should not to publish new builds into repository
-
# if project of builds has been removed from repository.
-
BuildList.where(
-
project_id: projects_for_cleanup.map{ |k| k.split('-')[testing ? 1 : 0] }.uniq,
-
save_to_repository_id: save_to_repository_id,
-
status: [BuildList::BUILD_PUBLISH, BuildList::BUILD_PUBLISH_INTO_TESTING]
-
).update_all(status: BuildList::FAILED_PUBLISH)
-
end
-
-
1
def build_lists
-
@build_lists ||= begin
-
build_lists = BuildList.
-
where(new_core: true, status: (testing ? BuildList::BUILD_PUBLISH_INTO_TESTING : BuildList::BUILD_PUBLISH)).
-
where(save_to_repository_id: save_to_repository_id).
-
where(build_for_platform_id: build_for_platform_id).
-
order(:updated_at)
-
locked_ids = Redis.current.lrange(LOCKED_BUILD_LISTS, 0, -1)
-
build_lists = build_lists.where('build_lists.id NOT IN (?)', locked_ids) if locked_ids.present?
-
build_lists = build_lists.limit(1500)
-
filter_build_lists_without_packages(build_lists.to_a)
-
end
-
end
-
-
end
-
end
-
1
module FileStoreService
-
1
class File
-
-
1
URL = APP_CONFIG['file_store_url']
-
-
1
attr_accessor :sha1, :data
-
-
# @param [String] sha1
-
# @param [Hash] data:
-
# - [String] path - path to file
-
# - [String] fullname - file name
-
1
def initialize(sha1: nil, data: {})
-
@sha1, @data = sha1, data
-
end
-
-
1
def exist?
-
resp = JSON(RestClient.get "#{URL}/api/v1/file_stores.json", params: {hash: sha1})
-
if resp[0].respond_to?('[]') && resp[0]['file_name'] && resp[0]['sha1_hash']
-
true
-
else
-
false
-
end
-
rescue # Dont care about it
-
return false
-
end
-
-
1
def save
-
sha1 = Digest::SHA1.hexdigest(::File.read(data[:path]))
-
return sha1 if exist?
-
-
resource = RestClient::Resource.new("#{URL}/api/v1/upload", user: token)
-
file = ::File.new(data[:path])
-
# Hook for RestClient
-
# See: [RestClient::Payload#create_file_field](https://github.com/rest-client/rest-client/blob/master/lib/restclient/payload.rb#L202-L215)
-
fullname = data[:fullname]
-
file.define_singleton_method(:original_filename) { fullname }
-
resp = resource.post(file_store: { file: file })
-
resp = JSON(resp)
-
-
if resp.respond_to?(:[]) && resp['sha1_hash'].present?
-
resp['sha1_hash']
-
else
-
nil
-
end
-
rescue RestClient::UnprocessableEntity => e # 422, file already exist
-
return sha1
-
rescue # Dont care about it
-
return nil
-
end
-
-
1
def destroy
-
uri = URI(URL)
-
Net::HTTP.start(uri.host, uri.port) do |http|
-
req = Net::HTTP::Delete.new("/api/v1/file_stores/#{sha1}.json")
-
req.basic_auth token, ''
-
http.request(req)
-
end
-
rescue # Dont care about it
-
end
-
-
1
protected
-
-
1
def token
-
Rails.cache.fetch([FileStoreService::File, :token], expires_in: 10.minutes) do
-
User.find_by(uname: 'file_store').authentication_token
-
end
-
end
-
-
end
-
end
-
# # See: https://github.com/bootstrap-ruby/will_paginate-bootstrap/blob/master/lib/bootstrap_pagination/bootstrap_renderer.rb
-
# class BootstrapLinkRenderer < WillPaginate::ActionView::LinkRenderer
-
-
# ELLIPSIS = "…"
-
-
# def to_html
-
# list_items = pagination.map do |item|
-
# case item
-
# when Fixnum
-
# page_number(item)
-
# else
-
# send(item)
-
# end
-
# end.join(@options[:link_separator])
-
-
# tag("ul", list_items, class: ul_class)
-
# end
-
-
# def container_attributes
-
# super.except(*[:link_options])
-
# end
-
-
# protected
-
-
# def page_number(page)
-
# link_options = @options[:link_options] || {}
-
-
# if page == current_page
-
# tag("li", tag("span", page), class: "active")
-
# else
-
# tag("li", link(page, page, link_options.merge(rel: rel_value(page))))
-
# end
-
# end
-
-
# def previous_or_next_page(page, text, classname)
-
# link_options = @options[:link_options] || {}
-
-
# if page
-
# tag("li", link(text, page, link_options), class: classname)
-
# else
-
# tag("li", tag("span", text), class: "%s disabled" % classname)
-
# end
-
# end
-
-
# def gap
-
# tag("li", tag("span", ELLIPSIS), class: "disabled")
-
# end
-
-
# def previous_page
-
# num = @collection.current_page > 1 && @collection.current_page - 1
-
# previous_or_next_page(num, @options[:previous_label], "prev")
-
# end
-
-
# def next_page
-
# num = @collection.current_page < @collection.total_pages && @collection.current_page + 1
-
# previous_or_next_page(num, @options[:next_label], "next")
-
# end
-
-
# def ul_class
-
# ["pagination", @options[:class]].compact.join(" ")
-
# end
-
# end
-
1
class Object
-
1
def with_skip
-
begin
-
Thread.current[:skip] = true
-
yield
-
ensure
-
Thread.current[:skip] = false
-
end
-
end
-
end
-
1
require 'charlock_holmes/string'
-
-
1
class String
-
1
def default_encoding!
-
117
default_encoding = Encoding.default_internal || Encoding::UTF_8
-
117
if ascii_only? # no need to encode if ascii
-
117
force_encoding(default_encoding)
-
else # should encode
-
options = {invalid: :replace, undef: :replace, replace: ''}
-
if encoding.name == 'UTF-8'
-
encode!(default_encoding, 'UTF-8', options)
-
elsif (detected = detect_encoding) && detected[:encoding]
-
force_encoding(detected[:encoding]).encode!(default_encoding, detected[:encoding], options)
-
end
-
scrub('')
-
raise unless valid_encoding? # check result
-
end
-
117
self
-
rescue
-
replace "--broken encoding: #{detect_encoding[:encoding] || 'unknown'}"
-
# ensure
-
# return self
-
end
-
-
# same as reverse.truncate.reverse
-
1
def rtruncate(length, options = {})
-
chars = self.dup.mb_chars
-
return self if chars.length <= length
-
options[:omission] ||= "..."
-
options[:separator] ||= '/'
-
-
start = chars.length - length + options[:omission].mb_chars.length
-
stop = options[:separator] ? (chars.index(options[:separator].mb_chars, start) || start) : start
-
"#{options[:omission]}#{chars[stop..-1]}".to_s
-
end
-
end
-
1
module Gollum
-
1
class Wiki
-
# Public: Applies a reverse diff for a given page. If only 1 SHA is given,
-
# the reverse diff will be taken from its parent (^SHA...SHA). If two SHAs
-
# are given, the reverse diff is taken from SHA1...SHA2.
-
#
-
# page - The Gollum::Page to delete.
-
# sha1 - String SHA1 of the earlier parent if two SHAs are given,
-
# or the child.
-
# sha2 - Optional String SHA1 of the child.
-
# commit - The commit Hash details:
-
# :message - The String commit message.
-
# :name - The String author full name.
-
# :email - The String email address.
-
# :parent - Optional Grit::Commit parent to this update.
-
#
-
# Returns a String SHA1 of the new commit, or nil if the reverse diff does
-
# not apply.
-
1
def revert_page_with_committer(page, sha1, sha2 = nil, commit = {})
-
if sha2.is_a?(Hash)
-
commit = sha2
-
sha2 = nil
-
end
-
-
multi_commit = false
-
-
patch = full_reverse_diff_for(page, sha1, sha2)
-
committer = if obj = commit[:committer]
-
multi_commit = true
-
obj
-
else
-
Committer.new(self, commit)
-
end
-
parent = committer.parents[0]
-
committer.options[:tree] = @repo.git.apply_patch(parent.sha, patch)
-
return false unless committer.options[:tree]
-
committer.after_commit do |index, sha|
-
@access.refresh
-
-
files = []
-
if page
-
files << [page.path, page.name, page.format]
-
else
-
# Grit::Diff can't parse reverse diffs.... yet
-
patch.each_line do |line|
-
if line =~ %r{^diff --git b/.+? a/(.+)$}
-
path = $1
-
ext = ::File.extname(path)
-
name = ::File.basename(path, ext)
-
if format = ::Gollum::Page.format_for(ext)
-
files << [path, name, format]
-
end
-
end
-
end
-
end
-
-
files.each do |(path, name, format)|
-
dir = ::File.dirname(path)
-
dir = '' if dir == '.'
-
index.update_working_dir(dir, name, format)
-
end
-
end
-
-
multi_commit ? committer : committer.commit
-
end
-
1
alias_method :revert_page_without_committer, :revert_page
-
1
alias_method :revert_page, :revert_page_with_committer
-
-
1
def revert_commit_with_committer(sha1, sha2 = nil, commit = {})
-
revert_page_with_committer(nil, sha1, sha2, commit)
-
end
-
1
alias_method :revert_commit_without_committer, :revert_commit
-
1
alias_method :revert_commit, :revert_commit_with_committer
-
end
-
end
-
1
module Grit
-
1
class Commit
-
-
# Fix: NoMethodError: undefined method 'touch' for Grit::Commit
-
# see: model Comment belongs_to :commentable
-
1
def touch
-
true
-
end
-
end
-
-
1
class Submodule
-
1
def binary?
-
false
-
end
-
end
-
-
1
class Blob
-
1
include Linguist::BlobHelper
-
-
1
MAX_VIEW_SIZE = 2.megabytes
-
1
MAX_DATA_SIZE = 50.megabytes
-
-
1
def data_with_limit
-
!huge? ? data_without_limit : nil # 'Error: blob is too big'
-
end
-
-
1
def data_without_limit
-
data
-
end
-
-
1
def large?
-
size.to_i > MAX_VIEW_SIZE
-
end
-
-
1
def huge?
-
size.to_i > MAX_DATA_SIZE
-
end
-
-
1
def render_as
-
@render_as ||= case
-
when large?; :binary
-
when image?; :image
-
when text?; :text
-
else
-
:binary
-
end
-
end
-
-
1
attr_accessor :raw_mime_type
-
1
def raw_mime_type
-
return @raw_mime_type if @raw_mime_type.present?
-
if mime_type == 'text/rpm-spec'
-
@raw_mime_type = 'text/x-rpm-spec'
-
else
-
@raw_mime_type = Linguist::Language.detect(self).try(:lexer).try(:mimetypes).try(:first)
-
@raw_mime_type ||= DEFAULT_MIME_TYPE
-
@raw_mime_type.gsub!('application', 'text')
-
@raw_mime_type
-
end
-
end
-
end
-
-
1
class Repo
-
1
def branches_and_tags
-
branches + tags # @branches_and_tags ||= # ???
-
end
-
-
1
def diff(a, b, *paths)
-
diff = self.git.native('diff', {}, "#{a}...#{b}", '--', *paths)
-
if diff =~ /diff --git a/
-
diff = diff.sub(/.*?(diff --git a)/m, '\1')
-
else
-
diff = ''
-
end
-
Diff.list_from_string(self, diff)
-
end
-
-
# The diff stats for the given treeish
-
# git diff --numstat -M a...b
-
#
-
# +a+ is the base treeish
-
# +b+ is the head treeish
-
#
-
# Returns Grit::DiffStat[]
-
1
def diff_stats(a,b)
-
stats = []
-
lines = self.git.native(:diff, {numstat: true}, "#{a}...#{b}").split("\n")
-
while !lines.empty?
-
files = []
-
while lines.first =~ /^([-\d]+)\s+([-\d]+)\s+(.+)/
-
additions, deletions, filename = lines.shift.gsub(' => ', '=>').split
-
additions, deletions = additions.to_i, deletions.to_i
-
stat = DiffStat.new filename, additions, deletions
-
stats << stat
-
end
-
end
-
stats
-
end
-
end
-
end
-
-
1
Grit::Git.git_timeout = 60
-
# Grit::Git.git_max_size = 5.megabytes
-
# Grit.debug = true
-
1
GAP_REPO_PATH = '/tmp/gap_repo.git'
-
1
unless File.directory? GAP_REPO_PATH
-
Grit::Repo.init_bare(GAP_REPO_PATH)
-
# FileUtils.chmod "a-w", GAP_REPO_PATH
-
end
-
# Patch to use paperclip with nginx upload module
-
1
module Paperclip
-
1
class Attachment
-
1
class UploadedPath
-
1
attr_reader :original_filename, :content_type, :size, :path
-
1
def initialize(uploaded_file)
-
@original_filename = uploaded_file["name"].downcase
-
@content_type = uploaded_file["content_type"].to_s.strip
-
@file_size = uploaded_file["size"].to_i
-
@path = uploaded_file["path"]
-
end
-
-
# TODO remove failed files
-
-
1
def to_tempfile; self; end
-
-
1
def size; @file_size; end
-
-
1
def close; end
-
1
def closed?; true; end
-
end
-
-
1
def assign_with_upload(uploaded_file)
-
uploaded_file = UploadedPath.new(uploaded_file) if uploaded_file.is_a?(Hash)
-
assign_without_upload(uploaded_file)
-
end
-
1
alias_method :assign_without_upload, :assign
-
1
alias_method :assign, :assign_with_upload
-
end
-
end
-
1
require 'posix/spawn'
-
-
1
module POSIX
-
1
module Spawn
-
1
class Child
-
1
include POSIX::Spawn
-
1
private
-
# Start a select loop writing any input on the child's stdin and reading
-
# any output from the child's stdout or stderr.
-
#
-
# input - String input to write on stdin. May be nil.
-
# stdin - The write side IO object for the child's stdin stream.
-
# stdout - The read side IO object for the child's stdout stream.
-
# stderr - The read side IO object for the child's stderr stream.
-
# timeout - An optional Numeric specifying the total number of seconds
-
# the read/write operations should occur for.
-
#
-
# Returns an [out, err] tuple where both elements are strings with all
-
# data written to the stdout and stderr streams, respectively.
-
# Raises TimeoutExceeded when all data has not been read / written within
-
# the duration specified in the timeout argument.
-
# Raises MaximumOutputExceeded when the total number of bytes output
-
# exceeds the amount specified by the max argument.
-
1
def read_and_write(input, stdin, stdout, stderr, timeout=nil, max=nil)
-
12
max = nil if max && max <= 0
-
12
@out, @err = '', ''
-
12
offset = 0
-
-
# force all string and IO encodings to BINARY under 1.9 for now
-
#if @out.respond_to?(:force_encoding) and stdin.respond_to?(:set_encoding)
-
# [stdin, stdout, stderr].each do |fd|
-
# fd.set_encoding('BINARY', 'BINARY')
-
# end
-
# @out.force_encoding('BINARY')
-
# @err.force_encoding('BINARY')
-
# input = input.dup.force_encoding('BINARY') if input
-
#end
-
-
12
timeout = nil if timeout && timeout <= 0.0
-
12
@runtime = 0.0
-
12
start = Time.now
-
-
12
readers = [stdout, stderr]
-
writers =
-
12
if input
-
[stdin]
-
else
-
12
stdin.close
-
12
[]
-
end
-
12
slice_method = input.respond_to?(:byteslice) ? :byteslice : :slice
-
12
t = timeout
-
-
12
while readers.any? || writers.any?
-
24
ready = IO.select(readers, writers, readers + writers, t)
-
24
raise TimeoutExceeded if ready.nil?
-
-
# write to stdin stream
-
24
ready[1].each do |fd|
-
begin
-
boom = nil
-
size = fd.write_nonblock(input)
-
input = input.send(slice_method, size..-1)
-
rescue Errno::EPIPE => boom
-
rescue Errno::EAGAIN, Errno::EINTR
-
end
-
if boom || input.bytesize == 0
-
stdin.close
-
writers.delete(stdin)
-
end
-
end
-
-
# read from stdout and stderr streams
-
24
ready[0].each do |fd|
-
36
buf = (fd == stdout) ? @out : @err
-
begin
-
36
buf << fd.readpartial(BUFSIZE)
-
rescue Errno::EAGAIN, Errno::EINTR
-
rescue EOFError
-
24
readers.delete(fd)
-
24
fd.close
-
end
-
end
-
-
# keep tabs on the total amount of time we've spent here
-
24
@runtime = Time.now - start
-
24
if timeout
-
24
t = timeout - @runtime
-
24
raise TimeoutExceeded if t < 0.0
-
end
-
-
# maybe we've hit our max output
-
24
if max && ready[0].any? && (@out.size + @err.size) > max
-
raise MaximumOutputExceeded
-
end
-
end
-
12
[@out.mb_chars.default_encoding!, @err.mb_chars.default_encoding!]
-
end
-
end
-
end
-
end
-
1
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
-
if html_tag =~ /<label/
-
%|<div class="fieldWithErrors">#{html_tag} <span class="error">#{[instance.error_message].join(', ')}</span></div>|.html_safe
-
else
-
html_tag
-
end
-
end
-
1
class ReservedNameValidator < ActiveModel::EachValidator
-
RESERVED_NAMES = %w{
-
1
about account add admin administrator api autocomplete_group_uname
-
app apps archive archives auth
-
blog
-
config connect contact create commit commits
-
dashboard delete direct_messages download downloads
-
edit email
-
faq favorites feed feeds follow followers following
-
help home
-
invitations invite
-
jobs
-
login log-in log_in logout log-out log_out logs
-
map maps
-
new none
-
oauth oauth_clients openid
-
privacy
-
register remove replies rss root
-
save search sessions settings
-
signup sign-up sign_up signin sign-in sign_in signout sign-out sign_out
-
sitemap ssl subscribe
-
teams terms test tour trends tree
-
unfollow unsubscribe upload uploads url user
-
widget widgets wiki
-
xfn xmpp
-
}
-
-
1
def reserved_names
-
12
@reserved_names ||= RESERVED_NAMES +
-
425
Rails.application.routes.routes.map{|r| r.path.spec.to_s.match(/^\/([\w-]+)/)[1] rescue nil}.uniq.compact # current routes
-
end
-
-
1
def validate_each(record, attribute, value)
-
12
if reserved_names.include?(value.to_s.downcase)
-
record.errors.add(attribute, :exclusion, options.merge(value: value))
-
end
-
end
-
end
-
1
module Rosa
-
1
module Constraints
-
1
class Owner
-
1
def initialize(class_name, bang = false)
-
4
@class_name = class_name
-
4
@finder = 'find_by_insensitive_uname'
-
4
@finder << '!' if bang
-
end
-
-
1
def matches?(request)
-
@class_name.send(@finder, request.params[:uname]).present?
-
end
-
end
-
-
1
class AdminAccess
-
1
def self.matches?(request)
-
!!request.env['warden'].user.try(:admin?)
-
end
-
end
-
-
1
class Treeish
-
1
def self.matches?(request)
-
if (params = request.path_parameters) && params[:treeish] # parse existing branch (tag) and path
-
branch_or_tag = begin
-
(p = Project.find_by_owner_and_name params[:name_with_owner]) &&
-
p.repo.branches_and_tags.map(&:name).sort{|a,b| b.length <=> a.length}.detect{|b| params[:treeish].start_with?(b)} ||
-
params[:treeish].split('/').first
-
end
-
if path = params[:treeish].sub(branch_or_tag, '')[1..-1] and path.present?
-
params[:path] = File.join([path, params[:path]].compact)
-
end
-
params[:treeish] = branch_or_tag
-
end
-
true
-
end
-
end
-
end
-
end
-
1
class Gollum::BlobEntry
-
1
def name
-
@name ||= begin
-
fname = ::File.basename(@path)
-
fname = fname.gsub(/\\\d+/).each { |q| q[1..-1].to_i(8).chr }.force_encoding('utf-8')
-
fname.gsub!(/^"/, '')
-
fname.gsub!(/"$/, '')
-
fname
-
end
-
end
-
end
-
1
Dir[File.join(File.dirname(__FILE__), 'plugins', '*.rb')].each do |f|
-
4
$:.unshift File.dirname(f)
-
4
require f
-
end
-
1
module Grack
-
1
extend ActiveSupport::Autoload
-
-
1
autoload :Base
-
1
autoload :Auth
-
1
autoload :Handler
-
end
-
1
module Grack
-
1
class Auth < Base
-
1
def initialize(app)
-
1
@app = app
-
end
-
-
# TODO tests!!!
-
1
def _call(env)
-
super
-
if git?
-
return render_not_found if project.blank?
-
-
return ::Rack::Auth::Basic.new(@app) do |u, p|
-
user = User.auth_by_token_or_login_pass(u, p) and
-
ability = ProjectPolicy.new(user, project).send("#{action}?") and
-
ENV['GL_ID'] = "user-#{user.id}" and
-
ENV['GL_REPO_NAME'] = project.path
-
end.call(env) unless project.public? && read? # need auth
-
end
-
@app.call(env) # next app in stack
-
end
-
end
-
end
-
1
module Grack
-
1
class Base # abstract
-
1
def call(env)
-
dup._call(env)
-
end
-
-
1
protected
-
-
1
def _call(env)
-
@env = env
-
@project = nil
-
end
-
-
1
def git?
-
@env['HTTP_USER_AGENT'] =~ /^git\//
-
end
-
-
1
def read?
-
(get? && !(@env['REQUEST_URI'] =~ /git-receive-pack$/)) ||
-
(post? && !(@env['REQUEST_URI'] =~ /git-upload-pack$/).nil?)
-
end
-
-
1
def write?
-
!read?
-
end
-
-
1
def get?
-
@env['REQUEST_METHOD'] == 'GET'
-
end
-
-
1
def post?
-
@env['REQUEST_METHOD'] == 'POST'
-
end
-
-
1
def action
-
write? ? :write : :read
-
end
-
-
1
def project
-
@project ||= begin
-
uname, name = @env['PATH_INFO'].split('/')[1,2]
-
name.gsub!(/(\.wiki)?\.git$/, '')
-
Project.find_by_owner_and_name uname, name
-
end
-
end
-
-
1
PLAIN_TYPE = {"Content-Type" => "text/plain"}
-
-
1
def render_not_found
-
[404, PLAIN_TYPE, ["Not Found"]]
-
end
-
-
1
def render_no_access
-
[403, PLAIN_TYPE, ["Forbidden"]]
-
end
-
end
-
end
-
-
# ({"HTTP_ACCEPT"=>"*/*", "HTTP_HOST"=>"localhost:3000", "SERVER_NAME"=>"localhost", "rack.url_scheme"=>"http", "PASSENGER_CONNECT_PASSWORD"=>"xbRC6murG5bIDTsaed8ksaZhjf8yFsadlX4QL0qWNbS", "HTTP_USER_AGENT"=>"git/1.7.7.2", "PASSENGER_SPAWN_METHOD"=>"smart-lv2", "PASSENGER_FRIENDLY_ERROR_PAGES"=>"true", "CONTENT_LENGTH"=>"0", "rack.errors"=>#<IO:0x108494a90>, "SERVER_PROTOCOL"=>"HTTP/1.1", "action_dispatch.secret_token"=>"df2fb72d477491cf15ef0f93449bcb59c3412c255c2386e07772935565c1b6ad23539ed804b8f12e3221e47abb78f5b679693c391acb33477be0e633e7a2e2a4", "rack.run_once"=>false, "rack.version"=>[1, 0], "REMOTE_ADDR"=>"127.0.0.1", "SERVER_SOFTWARE"=>"nginx/1.0.6", "PASSENGER_MIN_INSTANCES"=>"1", "PATH_INFO"=>"/codefoundry.git/info/refs", "SERVER_ADDR"=>"127.0.0.1", "SCRIPT_NAME"=>"", "action_dispatch.parameter_filter"=>[:password], "action_dispatch.show_exceptions"=>true, "rack.multithread"=>false, "PASSENGER_USER"=>"", "PASSENGER_ENVIRONMENT"=>"development", "PASSENGER_SHOW_VERSION_IN_HEADER"=>"true", "rack.multiprocess"=>true, "REMOTE_PORT"=>"49387", "REQUEST_URI"=>"/codefoundry.git/info/refs", "SERVER_PORT"=>"3000", "SCGI"=>"1", "PASSENGER_APP_TYPE"=>"rack", "PASSENGER_USE_GLOBAL_QUEUE"=>"true", "REQUEST_METHOD"=>"GET", "PASSENGER_GROUP"=>"", "PASSENGER_DEBUGGER"=>"false", "DOCUMENT_ROOT"=>"/Users/pasha/Sites/rosa-build/public", "_"=>"_", "PASSENGER_FRAMEWORK_SPAWNER_IDLE_TIME"=>"-1", "UNION_STATION_SUPPORT"=>"false", "rack.input"=>#<PhusionPassenger::Utils::RewindableInput:0x10bb55a20 @rewindable_io=nil, @io=#<PhusionPassenger::Utils::UnseekableSocket:0x10bb56c90 @socket=#<UNIXSocket:0x10bb56b28>>, @unlinked=false>, "HTTP_PRAGMA"=>"no-cache", "QUERY_STRING"=>"", "PASSENGER_APP_SPAWNER_IDLE_TIME"=>"-1"}) (process 41940, thread #<Thread:0x1084a1268>)
-
# {"rack.session"=>{}, "HTTP_ACCEPT"=>"*/*", "HTTP_HOST"=>"localhost:3000", "SERVER_NAME"=>"localhost", "action_dispatch.remote_ip"=>#<ActionDispatch::RemoteIp::RemoteIpGetter:0x10b621338 @check_ip_spoofing=true, @env={...}, @trusted_proxies=/(^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.)/i>, "rack.url_scheme"=>"http", "PASSENGER_CONNECT_PASSWORD"=>"dljpLA91qGH4v2gwaccoAxFysOmSkEFbRtPyPOe9953", "HTTP_USER_AGENT"=>"git/1.7.7.2", "PASSENGER_SPAWN_METHOD"=>"smart-lv2", "PASSENGER_FRIENDLY_ERROR_PAGES"=>"true", "CONTENT_LENGTH"=>"0", "action_dispatch.request.unsigned_session_cookie"=>{}, "rack.errors"=>#<IO:0x10724baa0>, "SERVER_PROTOCOL"=>"HTTP/1.1", "action_dispatch.secret_token"=>"df2fb72d477491cf15ef0f93449bcb59c3412c255c2386e07772935565c1b6ad23539ed804b8f12e3221e47abb78f5b679693c391acb33477be0e633e7a2e2a4", "rack.run_once"=>false, "rack.version"=>[1, 0], "REMOTE_ADDR"=>"127.0.0.1", "SERVER_SOFTWARE"=>"nginx/1.0.6", "PASSENGER_MIN_INSTANCES"=>"1", "PATH_INFO"=>"/pasha/mc.git/info/refs", "SERVER_ADDR"=>"127.0.0.1", "SCRIPT_NAME"=>"", "action_dispatch.parameter_filter"=>[:password], "action_dispatch.show_exceptions"=>true, "rack.multithread"=>false, "PASSENGER_USER"=>"", "PASSENGER_ENVIRONMENT"=>"development", "PASSENGER_SHOW_VERSION_IN_HEADER"=>"true", "action_dispatch.cookies"=>{}, "rack.multiprocess"=>true, "REMOTE_PORT"=>"49643", "REQUEST_URI"=>"/pasha/mc.git/info/refs", "SERVER_PORT"=>"3000", "SCGI"=>"1", "PASSENGER_APP_TYPE"=>"rack", "PASSENGER_USE_GLOBAL_QUEUE"=>"true", "rack.session.options"=>{:httponly=>true, :expire_after=>nil, :domain=>nil, :path=>"/", :secure=>false, :id=>nil}, "REQUEST_METHOD"=>"GET", "PASSENGER_GROUP"=>"", "PASSENGER_DEBUGGER"=>"false", "DOCUMENT_ROOT"=>"/Users/pasha/Sites/rosa-build/public", "warden"=>Warden::Proxy:2242130160 @config={:failure_app=>Devise::FailureApp, :default_scope=>:user, :intercept_401=>false, :scope_defaults=>{}, :default_strategies=>{:user=>[:rememberable, :database_authenticatable]}}, "_"=>"_", "PASSENGER_FRAMEWORK_SPAWNER_IDLE_TIME"=>"-1", "UNION_STATION_SUPPORT"=>"false", "rack.input"=>#<PhusionPassenger::Utils::RewindableInput:0x10b6225f8 @rewindable_io=nil, @io=#<PhusionPassenger::Utils::UnseekableSocket:0x10a8f5a10 @socket=#<UNIXSocket:0x10b623700>>, @unlinked=false>, "HTTP_PRAGMA"=>"no-cache", "QUERY_STRING"=>"", "PASSENGER_APP_SPAWNER_IDLE_TIME"=>"-1"}
-
1
module Grack
-
1
class Handler < Base
-
1
def initialize(app, config)
-
1
@app = app
-
1
@config = config
-
end
-
-
1
def _call(env)
-
super
-
if git?
-
Grack::App.new(@config).call(env)
-
else
-
@app.call(env)
-
end
-
end
-
end
-
end
-
1
require 'redcarpet/render/gitlab_html.rb'
-
1
class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
-
-
1
attr_reader :template
-
1
alias_method :h, :template
-
-
1
def initialize(template, options = {})
-
@template = template
-
@project = @template.instance_variable_get("@project")
-
@options = options.dup
-
super options
-
end
-
-
1
def block_code(code, language)
-
# New lines are placed to fix an rendering issue
-
# with code wrapped inside <h1> tag for next case:
-
#
-
# # Title kinda h1
-
#
-
# ruby code here
-
#
-
<<-HTML
-
-
<div class="highlighted-data #{h.user_color_scheme_class}">
-
<div class="highlight">
-
<pre><code class="#{language}">#{h.send(:html_escape, code)}</code></pre>
-
</div>
-
</div>
-
-
HTML
-
end
-
-
1
def link(link, title, content)
-
h.link_to_gfm(content, link, title: title)
-
end
-
-
1
def header(text, level)
-
if @options[:no_header_anchors]
-
"<h#{level}>#{text}</h#{level}>"
-
else
-
id = ActionController::Base.helpers.strip_tags(h.gfm(text)).downcase() \
-
.gsub(/[^a-z0-9_-]/, '-').gsub(/-+/, '-').gsub(/^-/, '').gsub(/-$/, '')
-
"<h#{level} id=\"#{id}\">#{text}<a href=\"\##{id}\"></a></h#{level}>"
-
end
-
end
-
-
1
def postprocess(full_document)
-
unless @template.instance_variable_get("@project_wiki") || @project.nil?
-
full_document = h.create_relative_links(full_document)
-
end
-
h.gfm(full_document)
-
end
-
end
-
1
module RosaPresenter
-
1
extend ActiveSupport::Autoload
-
-
1
autoload :Activation
-
1
autoload :Base
-
-
1
VERSION = "0.0.1"
-
end
-
-
1
ActionController::Base.send(:include, RosaPresenter::Activation)
-
# This code based on https://github.com/ihoka/viewtastic
-
1
module RosaPresenter
-
1
module Activation
-
1
def self.included(klass) # :nodoc:
-
1
klass.prepend_before_action :activate_rosa_presenter
-
end
-
-
1
private
-
1
def activate_rosa_presenter
-
3
RosaPresenter::Base.controller = self
-
end
-
end
-
end
-
# This code based on https://github.com/ihoka/viewtastic
-
1
module RosaPresenter
-
1
class Base
-
# include ActionDispatch::Routing::UrlFor
-
1
include ActionView::Helpers::UrlHelper
-
1
include ActionView::Helpers::TextHelper
-
1
include ActionView::Helpers::OutputSafetyHelper
-
1
include ActionView::Helpers::JavaScriptHelper
-
1
include Rails.application.routes.url_helpers
-
-
1
def initialize(item, opts)
-
end
-
-
1
def controller
-
Thread.current[:rosa_presenter_controller]
-
end
-
-
1
def helpers
-
controller.view_context
-
end
-
-
# TODO it needs to be refactored!
-
1
class << self
-
1
def present(item, opts, &block)
-
block.call(self.new(item, opts))
-
end
-
-
1
def present_collection(collection, &block)
-
res = collection.map {|e| self.new(*e)}
-
if block.present?
-
res = res.inject('') do |akk, presenter|
-
akk << block.call(presenter)
-
akk
-
end
-
end
-
return res
-
end
-
-
1
def controller=(value) #:nodoc:
-
3
Thread.current[:rosa_presenter_controller] = value
-
end
-
-
1
def controller #:nodoc:
-
Thread.current[:rosa_presenter_controller]
-
end
-
-
1
def activated? #:nodoc:
-
!controller.nil?
-
end
-
end
-
-
1
protected
-
-
1
def t(*args)
-
I18n.translate(*args)
-
end
-
-
1
def l(*args)
-
I18n.localize(*args)
-
end
-
end
-
end
-
1
require 'ffi'
-
-
1
module RPM
-
1
def self.compareVREs(vre1, vre2)
-
e1, v1, r1 = vre1
-
e2, v2, r2 = vre2
-
-
e1 = '0' if !e1.present?
-
e2 = '0' if !e2.present?
-
-
rc = compare_values(e1, e2)
-
if rc == 0
-
rc = compare_values(v1, v2)
-
if rc == 0
-
rc = compare_values(r1, r2)
-
end
-
end
-
-
return rc
-
end
-
-
1
class << self
-
1
private
-
-
1
def compare_values(val1, val2)
-
if !val1.present? && !val2.present?
-
return 0
-
elsif val1.present? && !val2.present?
-
return 1
-
elsif !val1.present? && val2.present?
-
return -1
-
end
-
-
return C.rpmvercmp(val1, val2)
-
end
-
end
-
-
1
module C
-
-
1
extend ::FFI::Library
-
-
begin
-
1
ffi_lib ['librpm.so.9', 'rpm']
-
rescue LoadError => e
-
raise(
-
"Can't find rpm libs on your system: #{e.message}"
-
)
-
end
-
-
1
attach_function 'rpmvercmp', [:string, :string], :int
-
-
end
-
end